diff options
author | Vitaly Novichkov <admin@wohlnet.ru> | 2018-06-19 15:04:50 +0300 |
---|---|---|
committer | Vitaly Novichkov <admin@wohlnet.ru> | 2018-06-19 15:04:50 +0300 |
commit | c0873278718da57ff19194377a35601027926c5f (patch) | |
tree | 6fca461d067a1e615788cecf7a74c175f0033fc8 | |
parent | 5a194eb263125e5505cca3ec0256c7efa348eaa4 (diff) | |
parent | 1026ecd3fd8dc865fb3a85ab4a130d9d1b494fd9 (diff) | |
download | libADLMIDI-c0873278718da57ff19194377a35601027926c5f.tar.gz libADLMIDI-c0873278718da57ff19194377a35601027926c5f.tar.bz2 libADLMIDI-c0873278718da57ff19194377a35601027926c5f.zip |
Merge branch 'master' into stable
82 files changed, 25464 insertions, 9003 deletions
diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..490755b --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,106 @@ +version: 1.3.{build} + +environment: + global: + PLATFORMTOOLSET: "v140" + matrix: + - BUILD_TYPE: Debug + COMPILER: MinGW + COMPILER_FAMILY: MinGW + GENERATOR: "MinGW Makefiles" + PLATFORM: Win32 + - BUILD_TYPE: Release + COMPILER: MinGW + COMPILER_FAMILY: MinGW + GENERATOR: "MinGW Makefiles" + PLATFORM: Win32 + - BUILD_TYPE: Debug + COMPILER: MinGW-w64 + COMPILER_FAMILY: MinGW + GENERATOR: "MinGW Makefiles" + PLATFORM: x64 + - BUILD_TYPE: Release + COMPILER: MinGW-w64 + COMPILER_FAMILY: MinGW + GENERATOR: "MinGW Makefiles" + PLATFORM: x64 + - BUILD_TYPE: Debug + COMPILER: MSVC15 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 14 2015 Win64" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + PLATFORM: x64 + PLATFORMTOOLSET: "v140_xp" + - BUILD_TYPE: Release + COMPILER: MSVC15 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 14 2015 Win64" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + PLATFORM: x64 + PLATFORMTOOLSET: "v140_xp" + - BUILD_TYPE: Debug + COMPILER: MSVC15 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 14 2015" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + PLATFORM: Win32 + PLATFORMTOOLSET: "v140_xp" + - BUILD_TYPE: Release + COMPILER: MSVC15 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 14 2015" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + PLATFORM: Win32 + PLATFORMTOOLSET: "v140_xp" + - BUILD_TYPE: Debug + COMPILER: MSVC17 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 15 2017 Win64" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" + PLATFORM: x64 + PLATFORMTOOLSET: "v141_xp" + - BUILD_TYPE: Release + COMPILER: MSVC17 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 15 2017 Win64" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" + PLATFORM: x64 + PLATFORMTOOLSET: "v141_xp" + - BUILD_TYPE: Debug + COMPILER: MSVC17 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 15 2017" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" + PLATFORM: Win32 + PLATFORMTOOLSET: "v141_xp" + - BUILD_TYPE: Release + COMPILER: MSVC17 + COMPILER_FAMILY: MSVC + GENERATOR: "Visual Studio 15 2017" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" + PLATFORM: Win32 + PLATFORMTOOLSET: "v141_xp" + +build_script: + - md build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% + - cd build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% + - if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH:C:\Program Files\Git\usr\bin;=% + - if [%COMPILER%]==[MinGW-w32] set PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%PATH:C:\Program Files\Git\usr\bin;=% + - if [%COMPILER%]==[MinGW-w64] set PATH=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH:C:\Program Files\Git\usr\bin;=% + - cmake -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_PREFIX_PATH=. -DCMAKE_INSTALL_PREFIX=libADLMIDI -DWITH_OLD_UTILS=ON -DWITH_GENADLDATA=OFF -DlibADLMIDI_STATIC=ON -DlibADLMIDI_SHARED=ON .. + - if [%COMPILER_FAMILY%]==[MinGW] cmake --build . --config %BUILD_TYPE% -- -j 2 + - if [%COMPILER_FAMILY%]==[MinGW] mingw32-make install + - if [%COMPILER_FAMILY%]==[MSVC] cmake --build . --config %BUILD_TYPE% --target install + - 7z a -t7z -mx9 "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" "libADLMIDI" + - move libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z .. + +artifacts: + - path: 'libADLMIDI-$(COMPILER)-$(BUILD_TYPE)-$(PLATFORM).7z' + +deploy: + - provider: Environment + name: WohlnetFTP + +#on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + diff --git a/CMakeLists.txt b/CMakeLists.txt index bda3e0b..c26d5ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required (VERSION 3.2) -project (libADLMIDI) +project (libADLMIDI C CXX) #=========================================================================================== # Strip garbage @@ -11,13 +11,21 @@ ELSEIF(NOT MSVC AND NOT MSDOS) set(LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--gc-sections -Wl,-s") ENDIF() -# Global optimization flags IF(NOT MSVC AND NOT MSDOS) +# Global optimization flags set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-omit-frame-pointer") +# Turn on all warnings + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") ENDIF() -if (CMAKE_BUILD_TYPE EQUAL "RELEASE") +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() + +string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) +if(CMAKE_BUILD_TYPE_LOWER EQUAL "release") add_definitions(-DNDEBUG) ENDIF() @@ -45,7 +53,7 @@ function(set_legacy_standard destTarget) if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) # Turn on warnings and legacy C/C++ standards to support more compilers target_compile_options(${destTarget} PRIVATE - $<$<COMPILE_LANGUAGE:C>:-Wall -pedantic -std=c90> + $<$<COMPILE_LANGUAGE:C>:-Wall -pedantic -std=c90 -Wno-long-long> $<$<COMPILE_LANGUAGE:CXX>:-Wall -pedantic -std=gnu++98> ) endif() @@ -53,26 +61,29 @@ function(set_legacy_standard destTarget) endfunction() #=========================================================================================== -option(WITH_MIDIPLAY "Build also demo MIDI player" OFF) -option(MIDIPLAY_WAVE_ONLY "Build Demo MIDI player without support of real time playing. It will output into WAV only." OFF) -option(WITH_ADLMIDI2 "Build also classic ADLMIDI player [EXPERIMENTAL]" OFF) -option(WITH_VLC_PLUGIN "Build also a plugin for VLC Media Player" OFF) -option(WITH_OLD_UTILS "Build also old utilities" OFF) -option(WITH_EMBEDDED_BANKS "Use embedded banks" ON) -option(WITH_GENADLDATA "Build and run full rebuild of embedded banks cache" OFF) -option(WITH_GENADLDATA_COMMENTS "Enable comments in generated ADLDATA cache file" OFF) -option(USE_DOSBOX_EMULATOR "Use DosBox 0.74 OPL3 emulator (semi-accurate, suggested for slow or mobile platforms)" ON) -option(USE_NUKED_EMULATOR "Use Nuked OPL3 emulator (most accurate, powerful)" ON) +option(libADLMIDI_STATIC "Build static library of libADLMIDI" ON) +option(libADLMIDI_SHARED "Build shared library of libADLMIDI" OFF) + option(WITH_CPP_EXTRAS "Build with support for C++ extras (features are can be found in 'adlmidi.hpp' header)" OFF) option(WITH_MIDI_SEQUENCER "Build with embedded MIDI sequencer. Disable this if you want use library in real-time MIDI drivers or plugins.)" ON) +option(WITH_EMBEDDED_BANKS "Use embedded banks" ON) +option(WITH_HQ_RESAMPLER "Build with support for high quality resampling" OFF) option(WITH_MUS_SUPPORT "Build with support for DMX MUS files)" ON) option(WITH_XMI_SUPPORT "Build with support for AIL XMI files)" ON) +option(USE_DOSBOX_EMULATOR "Use DosBox 0.74 OPL3 emulator (semi-accurate, suggested for slow or mobile platforms)" ON) +option(USE_NUKED_EMULATOR "Use Nuked OPL3 emulator (most accurate, powerful)" ON) -option(libADLMIDI_STATIC "Build static library of libADLMIDI" ON) -option(libADLMIDI_SHARED "Build shared library of libADLMIDI" OFF) +option(WITH_GENADLDATA "Build and run full rebuild of embedded banks cache" OFF) +option(WITH_GENADLDATA_COMMENTS "Enable comments in generated ADLDATA cache file" OFF) +option(WITH_MIDIPLAY "Build also demo MIDI player" OFF) +option(MIDIPLAY_WAVE_ONLY "Build Demo MIDI player without support of real time playing. It will output into WAV only." OFF) +option(WITH_ADLMIDI2 "Build also classic ADLMIDI player [EXPERIMENTAL]" OFF) +option(WITH_VLC_PLUGIN "Build also a plugin for VLC Media Player" OFF) +option(WITH_OLD_UTILS "Build also old utilities" OFF) option(EXAMPLE_SDL2_AUDIO "Build also a simple SDL2 demo MIDI player" OFF) + if(CMAKE_VERSION VERSION_EQUAL "3.1" OR CMAKE_VERSION VERSION_GREATER "3.1") set(CMAKE_CXX_STANDARD 11) endif() @@ -97,6 +108,14 @@ if(WITH_OLD_UTILS) list(APPEND libADLMIDI_INSTALLS adldumpmiles) endif() +if(WITH_ADLMIDI2 OR (WITH_EMBEDDED_BANKS AND WITH_GENADLDATA)) + find_package(OpenMP) +endif() + +if(WITH_HQ_RESAMPLER) + find_library(ZITA_RESAMPLER_LIBRARY "zita-resampler" REQUIRED) +endif() + if(WITH_EMBEDDED_BANKS) if(WITH_GENADLDATA) set(GEN_ADLDATA_SRC) @@ -107,10 +126,6 @@ if(WITH_EMBEDDED_BANKS) ${libADLMIDI_SOURCE_DIR}/utils/gen_adldata/ini/ini_processing.cpp ) - list(APPEND GEN_ADLDATA_SRC - ${libADLMIDI_SOURCE_DIR}/src/chips/opl_chip_base.cpp - ) - if(USE_DOSBOX_EMULATOR) set(HAS_EMULATOR TRUE) list(APPEND GEN_ADLDATA_SRC @@ -139,12 +154,20 @@ if(WITH_EMBEDDED_BANKS) if(NOT MSVC) target_link_libraries(gen_adldata pthread m stdc++) endif() - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR - CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR - "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.2) - message("Turned on C++11 on GCC/CLang/Intel") - target_compile_options(gen_adldata PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MinGW" OR + CMAKE_COMPILER_IS_MINGW) + if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 3.2) + message("Turned on C++11 on GCC/CLang/Intel/MinGW") + set_target_properties(gen_adldata PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + if(OPENMP_FOUND) + target_compile_options(gen_adldata PUBLIC "-fopenmp") + target_link_libraries(gen_adldata "-fopenmp") + endif() endif() else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") message("Turned on C++11 on MSVC") @@ -155,12 +178,16 @@ if(WITH_EMBEDDED_BANKS) target_compile_options(gen_adldata PUBLIC "-DADLDATA_WITH_COMMENTS") endif() - add_custom_target( - gen-adldata-run - COMMAND gen_adldata ${libADLMIDI_SOURCE_DIR}/src/adldata.cpp + set(ADLDATA_DATABASE + "${libADLMIDI_SOURCE_DIR}/src/adldata.cpp" + ) + add_custom_target(gen-adldata-run #OUTPUT ${ADLDATA_DATABASE} + COMMAND gen_adldata "${ADLDATA_DATABASE}" WORKING_DIRECTORY ${libADLMIDI_SOURCE_DIR} + DEPENDS gen_adldata "${libADLMIDI_SOURCE_DIR}/banks.ini" + COMMENT "Running Embedded FM banks database generation" + VERBATIM ) - add_dependencies(gen-adldata-run gen_adldata) endif() endif() @@ -193,10 +220,6 @@ else() endif() if(NOT DJGPP AND NOT MSDOS) - list(APPEND libADLMIDI_SOURCES - ${libADLMIDI_SOURCE_DIR}/src/chips/opl_chip_base.cpp - ) - if(USE_DOSBOX_EMULATOR) set(HAS_EMULATOR TRUE) list(APPEND libADLMIDI_SOURCES @@ -269,9 +292,9 @@ endif() add_library(ADLMIDI INTERFACE) if(libADLMIDI_SHARED) - target_link_libraries(ADLMIDI INTERFACE ADLMIDI_shared) + target_link_libraries(ADLMIDI INTERFACE ADLMIDI_shared) else() - target_link_libraries(ADLMIDI INTERFACE ADLMIDI_static) + target_link_libraries(ADLMIDI INTERFACE ADLMIDI_static) endif() if(WITH_MIDIPLAY) @@ -342,6 +365,7 @@ if(WITH_ADLMIDI2) set(ADLMIDI2_VIDEO_OUT_SUPPORT "TRUE") endif() + set(adlmidi2_src) list(APPEND adlmidi2_src ${libADLMIDI_SOURCE_DIR}/utils/adlmidi-2/midiplay.cc @@ -354,11 +378,11 @@ if(WITH_ADLMIDI2) add_executable(adlmidi2 ${adlmidi2_src}) if(ADLMIDI2_HAS_PUZZLE_GAME) - target_compile_options(adlmidi2 PUBLIC "-DSUPPORT_PUZZLE_GAME") + target_compile_definitions(adlmidi2 PUBLIC "-DSUPPORT_PUZZLE_GAME") endif() if(ADLMIDI2_VIDEO_OUT_SUPPORT) - target_compile_options(adlmidi2 PUBLIC "-DSUPPORT_VIDEO_OUTPUT") + target_compile_definitions(adlmidi2 PUBLIC "-DSUPPORT_VIDEO_OUTPUT") endif() if(WIN32) @@ -373,12 +397,20 @@ if(WITH_ADLMIDI2) message(FATAL_ERROR "ADLMIDI2 Requires C++ Extras. Please enable WITH_CPP_EXTRAS option!") endif() - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR - CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR - "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.2) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MinGW" OR + CMAKE_COMPILER_IS_MINGW) + if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 3.2) message("Turned on C++11 on GCC/CLang/Intel") - target_compile_options(adlmidi2 PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>) + set_target_properties(adlmidi2 PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + endif() + if(OPENMP_FOUND) + target_compile_options(adlmidi2 PUBLIC "-fopenmp") + target_link_libraries(adlmidi2 "-fopenmp") endif() else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") message("Turned on C++11 on MSVC") @@ -388,7 +420,7 @@ if(WITH_ADLMIDI2) if(libADLMIDI_SHARED) add_dependencies(adlmidi2 ADLMIDI_shared) # ========= WIP ========= - # set_target_properties(adlmidiplay PROPERTIES COMPILE_FLAGS "-Wl,-rpath='$$ORIGIN/../lib'") + set_target_properties(adlmidi2 PROPERTIES COMPILE_FLAGS "-Wl,-rpath='$$ORIGIN/../lib'") else() if(NOT libADLMIDI_STATIC) message(FATAL_ERROR "libADLMIDI is required to be built!") @@ -469,6 +501,17 @@ if(WITH_VLC_PLUGIN) endif() +if(WITH_HQ_RESAMPLER) + if(libADLMIDI_SHARED) + target_compile_definitions(ADLMIDI_shared PRIVATE -DADLMIDI_ENABLE_HQ_RESAMPLER) + target_link_libraries(ADLMIDI_shared PUBLIC "${ZITA_RESAMPLER_LIBRARY}") + endif() + if(libADLMIDI_STATIC) + target_compile_definitions(ADLMIDI_static PRIVATE -DADLMIDI_ENABLE_HQ_RESAMPLER) + target_link_libraries(ADLMIDI_static PUBLIC "${ZITA_RESAMPLER_LIBRARY}") + endif() +endif() + install(TARGETS ${libADLMIDI_INSTALLS} RUNTIME DESTINATION "bin" LIBRARY DESTINATION "lib" @@ -480,22 +523,33 @@ install(FILES include/adlmidi.hpp DESTINATION include/) +option(WITH_UNIT_TESTS "Enable unit testing" OFF) +if(WITH_UNIT_TESTS) + enable_testing() + add_subdirectory(test) +endif() + message("==== libADLMIDI options ====") +message("libADLMIDI_STATIC = ${libADLMIDI_STATIC}") +message("libADLMIDI_SHARED = ${libADLMIDI_SHARED}") +message("WITH_UNIT_TESTS = ${WITH_UNIT_TESTS}") + +message("WITH_CPP_EXTRAS = ${WITH_CPP_EXTRAS}") +message("WITH_MIDI_SEQUENCER = ${WITH_MIDI_SEQUENCER}") +message("WITH_EMBEDDED_BANKS = ${WITH_EMBEDDED_BANKS}") +message("WITH_HQ_RESAMPLER = ${WITH_HQ_RESAMPLER}") +message("WITH_MUS_SUPPORT = ${WITH_MUS_SUPPORT}") +message("WITH_XMI_SUPPORT = ${WITH_XMI_SUPPORT}") +message("USE_DOSBOX_EMULATOR = ${USE_DOSBOX_EMULATOR}") +message("USE_NUKED_EMULATOR = ${USE_NUKED_EMULATOR}") + +message("===== Utils and extras =====") +message("WITH_GENADLDATA = ${WITH_GENADLDATA}") +message("WITH_GENADLDATA_COMMENTS = ${WITH_GENADLDATA_COMMENTS}") + message("WITH_MIDIPLAY = ${WITH_MIDIPLAY}") -message("WITH_VLC_PLUGIN = ${WITH_VLC_PLUGIN}") message("MIDIPLAY_WAVE_ONLY = ${MIDIPLAY_WAVE_ONLY}") message("WITH_ADLMIDI2 = ${WITH_ADLMIDI2}") +message("WITH_VLC_PLUGIN = ${WITH_VLC_PLUGIN}") message("WITH_OLD_UTILS = ${WITH_OLD_UTILS}") -message("WITH_EMBEDDED_BANKS = ${WITH_EMBEDDED_BANKS}") -message("WITH_GENADLDATA = ${WITH_GENADLDATA}") -message("WITH_GENADLDATA_COMMENTS = ${WITH_GENADLDATA_COMMENTS}") -message("USE_DOSBOX_EMULATOR = ${USE_DOSBOX_EMULATOR}") -message("USE_NUKED_EMULATOR = ${USE_NUKED_EMULATOR}") -message("WITH_MIDI_SEQUENCER = ${WITH_MIDI_SEQUENCER}") -message("WITH_CPP_EXTRAS = ${WITH_CPP_EXTRAS}") -message("WITH_MUS_SUPPORT = ${WITH_MUS_SUPPORT}") -message("WITH_XMI_SUPPORT = ${WITH_XMI_SUPPORT}") -message("libADLMIDI_STATIC = ${libADLMIDI_STATIC}") -message("libADLMIDI_SHARED = ${libADLMIDI_SHARED}") message("EXAMPLE_SDL2_AUDIO = ${EXAMPLE_SDL2_AUDIO}") - @@ -9,7 +9,8 @@ Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 e [http://iki.fi/bisqwit/source/adlmidi.html](http://iki.fi/bisqwit/source/adlmidi.html) -[](https://semaphoreci.com/wohlstand/libadlmidi) +* Semaphore-CI: [](https://semaphoreci.com/wohlstand/libadlmidi) +* AppVeyor CI: [](https://ci.appveyor.com/project/Wohlstand/libadlmidi) # Differences with original tool * Reverb code has been removed. @@ -56,20 +57,35 @@ sudo make install ## Available CMake options + +### Library options * **CMAKE_PREFIX_PATH** - destinition folder where libADLMIDI will be installed. On Linux it is /usr/local/ by default. * **CMAKE_BUILD_TYPE** - Build types: **Debug** or **Release** -* **WITH_MIDIPLAY** - (ON/OFF, default OFF) Build demo MIDI player (Requires SDL2 and also pthread on Windows with MinGW) -* **WITH_VLC_PLUGIN** - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC version 2.2.2. Support for newer VLC versions and other platforms comming soon! -* **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows. Also, the **WITH_CPP_EXTRAS** flag must be enabled) + +* **libADLMIDI_STATIC** - (ON/OFF, default ON) Build static library +* **libADLMIDI_SHARED** - (ON/OFF, default OFF) Build shared library +* **WITH_UNIT_TESTS** - (ON/OFF, default OFF) Enable unit testing + * **WITH_CPP_EXTRAS** - (ON/OFF, default OFF) Build libADLMIDI with some extra public features for C++ language (for example, instrument testing API is available for C++ only). -* **WITH_OLD_UTILS** - (ON/OFF, default OFF) Build old utilities to dump some bank formats, made by original creator of ADLMIDI +* **WITH_MIDI_SEQUENCER** - (ON/OFF, default ON) Build with embedded MIDI sequencer. Disable this if you want use library in real-time MIDI drivers or plugins.) * **WITH_EMBEDDED_BANKS** - (ON/OFF, default ON) Enable or disable embedded banks (Original ADLMIDI and older versions of libADLMIDI are had embedded-only banks with no ability to load custom banks in runtime). -* **WITH_GENADLDATA** - (ON/OFF, default OFF) Build and execute the utility which will rebuild the embedded banks database (which is an adldata.cpp file). +* **WITH_HQ_RESAMPLER** - (ON/OFF, default OFF) Build with support for high quality resampling (requires zita-resampler to be installed) +* **WITH_MUS_SUPPORT** - (ON/OFF, default ON) Build with support for DMX MUS files) +* **WITH_XMI_SUPPORT** - (ON/OFF, default ON) Build with support for AIL XMI files) * **USE_DOSBOX_EMULATOR** - (ON/OFF, default ON) Enable support for DosBox 0.74 emulator. (Well-accurate and fast) * **USE_NUKED_EMULATOR** - (ON/OFF, default ON) Enable support for Nuked OPL3 emulator. (Very-accurate, needs more CPU power) -* **libADLMIDI_STATIC** - (ON/OFF, default ON) Build static library -* **libADLMIDI_SHARED** - (ON/OFF, default OFF) Build shared library + +### Utils and extras +* **WITH_GENADLDATA** - (ON/OFF, default OFF) Build and execute the utility which will rebuild the embedded banks database (which is an adldata.cpp file). +* **WITH_GENADLDATA_COMMENTS** - (ON/OFF, default OFF) Enable comments in generated ADLDATA cache file + +* **WITH_MIDIPLAY** - (ON/OFF, default OFF) Build demo MIDI player (Requires SDL2 and also pthread on Windows with MinGW) +* **MIDIPLAY_WAVE_ONLY** - (ON/OFF, default OFF) Build Demo MIDI player without support of real time playing. It will output into WAV only. +* **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows. Also, the **WITH_CPP_EXTRAS** flag must be enabled) +* **WITH_VLC_PLUGIN** - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC. Support for other platforms comming soon! +* **WITH_OLD_UTILS** - (ON/OFF, default OFF) Build old utilities to dump some bank formats, made by original creator of ADLMIDI +* **EXAMPLE_SDL2_AUDIO** - (ON/OFF, default OFF) Build also a simple SDL2 demo MIDI player ## You also can build library manually: @@ -135,6 +151,17 @@ To build that example you will need to have installed SDL2 library. * Add support of MIDI Format 2 files (FL Studio made MIDI-files are wired and opening of those files making lossy of tempo and some meta-information events) # Changelog +## 1.3.3 2018-06-19 + * Fixed an inability to load another custom bank without of library re-initialization + * Optimizing the MIDI banks management system for MultiBanks (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) + * Fixed incorrect 4-op counter which is still catch 4-op instruments on 2-op banks + * Fixed an incorrect processing of auto-flags + * Fixed incorrect initial MIDI tempo when MIDI file doesn't includes the tempo event + * Channel and Note Aftertouch features are now supported correctly! Aftertouch is the tremolo / vibrato, NOT A VOLUME! + * Updated DosBox OPL3 emulator up to r4111 of official DosBox trunk (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) + * The automatical choosing of 4 operator channels count has been improved (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) + * Added optional HQ resampler for Nuked OPL3 emulators which does usage of Zita-Resampler library (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) + ## 1.3.2 2018-04-24 * Added ability to disable MUS and XMI converters * Added ability to disable embedded MIDI sequencer to use library as RealTime synthesizer only or use any custom MIDI sequencer plugins. diff --git a/fm_banks/adldata-cache.dat b/fm_banks/adldata-cache.dat Binary files differindex bee5302..53f19dc 100644 --- a/fm_banks/adldata-cache.dat +++ b/fm_banks/adldata-cache.dat diff --git a/fm_banks/wopl_files/Apogee-IMF-90.wopl b/fm_banks/wopl_files/Apogee-IMF-90.wopl Binary files differindex 1a808b2..89b8c77 100644 --- a/fm_banks/wopl_files/Apogee-IMF-90.wopl +++ b/fm_banks/wopl_files/Apogee-IMF-90.wopl diff --git a/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl b/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl Binary files differindex 58362a5..957f950 100644 --- a/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl +++ b/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl diff --git a/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl b/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl Binary files differindex 6ec13ea..5512a07 100644 --- a/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl +++ b/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl diff --git a/include/adlmidi.h b/include/adlmidi.h index 56626bb..c64f55c 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -30,7 +30,7 @@ extern "C" { #define ADLMIDI_VERSION_MAJOR 1 #define ADLMIDI_VERSION_MINOR 3 -#define ADLMIDI_VERSION_PATCHLEVEL 2 +#define ADLMIDI_VERSION_PATCHLEVEL 3 #define ADLMIDI_TOSTR_I(s) #s #define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s) @@ -58,11 +58,12 @@ typedef short ADL_SInt16; enum ADLMIDI_VolumeModels { ADLMIDI_VolumeModel_AUTO = 0, - ADLMIDI_VolumeModel_Generic, - ADLMIDI_VolumeModel_CMF, - ADLMIDI_VolumeModel_DMX, - ADLMIDI_VolumeModel_APOGEE, - ADLMIDI_VolumeModel_9X + ADLMIDI_VolumeModel_Generic = 1, + ADLMIDI_VolumeModel_NativeOPL3 = 2, + ADLMIDI_VolumeModel_CMF = ADLMIDI_VolumeModel_NativeOPL3, + ADLMIDI_VolumeModel_DMX = 3, + ADLMIDI_VolumeModel_APOGEE = 4, + ADLMIDI_VolumeModel_9X = 5 }; enum ADLMIDI_SampleType @@ -110,6 +111,46 @@ extern int adl_getBanksCount(); /* Returns pointer to array of names of every bank */ extern const char *const *adl_getBankNames(); +/* Reference to dynamic bank */ +typedef struct ADL_Bank +{ + void *pointer[3]; +} ADL_Bank; + +/* Identifier of dynamic bank */ +typedef struct ADL_BankId +{ + ADL_UInt8 percussive, msb, lsb; +} ADL_BankId; + +/* Flags for dynamic bank access */ +enum ADL_BankAccessFlags +{ + ADLMIDI_Bank_Create = 1, /* create bank, allocating memory as needed */ + ADLMIDI_Bank_CreateRt = 1|2, /* create bank, never allocating memory */ +}; + +typedef struct ADL_Instrument ADL_Instrument; + +#if defined(ADLMIDI_UNSTABLE_API) +/* Preallocates a minimum number of bank slots. Returns the actual capacity. */ +extern int adl_reserveBanks(struct ADL_MIDIPlayer *device, unsigned banks); +/* Gets the bank designated by the identifier, optionally creating if it does not exist. */ +extern int adl_getBank(struct ADL_MIDIPlayer *device, const ADL_BankId *id, int flags, ADL_Bank *bank); +/* Gets the identifier of a bank. */ +extern int adl_getBankId(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id); +/* Removes a bank. */ +extern int adl_removeBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank); +/* Gets the first bank. */ +extern int adl_getFirstBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank); +/* Iterates to the next bank. */ +extern int adl_getNextBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank); +/* Gets the nth intrument in the bank [0..127]. */ +extern int adl_getInstrument(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins); +/* Sets the nth intrument in the bank [0..127]. */ +extern int adl_setInstrument(struct ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins); +#endif /* defined(ADLMIDI_UNSTABLE_API) */ + /*Sets number of 4-operator channels between all chips. By default, it is automatically re-calculating every bank change. If you want to specify custom number of four operator channels, @@ -141,7 +182,7 @@ extern void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_bri /*Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part)*/ extern void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn); -/*Enable or disable Logariphmic volume changer */ +/* !!!DEPRECATED!!! Enable or disable Logariphmic volume changer */ extern void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol); /*Set different volume range model */ @@ -336,6 +377,70 @@ extern void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_NoteHook noteHook /* Set debug message hook */ extern void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData); + +/**Instrument structures**/ + +enum +{ + ADLMIDI_InstrumentVersion = 0, +}; + +typedef enum ADL_InstrumentFlags +{ + /* Is two-operator single-voice instrument (no flags) */ + ADLMIDI_Ins_2op = 0x00, + /* Is true four-operator instrument */ + ADLMIDI_Ins_4op = 0x01, + /* Is pseudo four-operator (two 2-operator voices) instrument */ + ADLMIDI_Ins_Pseudo4op = 0x02, + /* Is a blank instrument entry */ + ADLMIDI_Ins_IsBlank = 0x04, + /* Mask of the flags range */ + ADLMIDI_Ins_ALL_MASK = 0x07, +} ADL_InstrumentFlags; + +typedef struct ADL_Operator +{ + /* AM/Vib/Env/Ksr/FMult characteristics */ + ADL_UInt8 avekf_20; + /* Key Scale Level / Total level register data */ + ADL_UInt8 ksl_l_40; + /* Attack / Decay */ + ADL_UInt8 atdec_60; + /* Systain and Release register data */ + ADL_UInt8 susrel_80; + /* Wave form */ + ADL_UInt8 waveform_E0; +} ADL_Operator; + +typedef struct ADL_Instrument +{ + /* Version of the instrument object */ + int version; + /* MIDI note key (half-tone) offset for an instrument (or a first voice in pseudo-4-op mode) */ + ADL_SInt16 note_offset1; + /* MIDI note key (half-tone) offset for a second voice in pseudo-4-op mode */ + ADL_SInt16 note_offset2; + /* MIDI note velocity offset (taken from Apogee TMB format) */ + ADL_SInt8 midi_velocity_offset; + /* Second voice detune level (taken from DMX OP2) */ + ADL_SInt8 second_voice_detune; + /* Percussion MIDI base tone number at which this drum will be played */ + ADL_UInt8 percussion_key_number; + /* Enum ADL_InstrumentFlags */ + ADL_UInt8 inst_flags; + /* Feedback&Connection register for first and second operators */ + ADL_UInt8 fb_conn1_C0; + /* Feedback&Connection register for third and fourth operators */ + ADL_UInt8 fb_conn2_C0; + /* Operators register data */ + ADL_Operator operators[4]; + /* Millisecond delay of sounding while key is on */ + ADL_UInt16 delay_on_ms; + /* Millisecond delay of sounding after key off */ + ADL_UInt16 delay_off_ms; +} ADL_Instrument; + #ifdef __cplusplus } #endif diff --git a/include/adlmidi.hpp b/include/adlmidi.hpp index 63f2abd..6d01b8d 100644 --- a/include/adlmidi.hpp +++ b/include/adlmidi.hpp @@ -24,24 +24,15 @@ #ifndef ADLMIDI_HPP #define ADLMIDI_HPP -#include "adlmidi.h" - -#include <stdint.h> -#include <vector> - -class OPL3; -class MIDIplay; +struct ADL_MIDIPlayer; class AdlInstrumentTester { - uint32_t cur_gm; - uint32_t ins_idx; - std::vector<uint32_t> adl_ins_list; - OPL3 *opl; - MIDIplay * play; + struct Impl; + Impl *P; public: - AdlInstrumentTester(ADL_MIDIPlayer *device); + explicit AdlInstrumentTester(ADL_MIDIPlayer *device); virtual ~AdlInstrumentTester(); // Find list of adlib instruments that supposedly implement this GM @@ -51,6 +42,10 @@ public: void NextGM(int offset); void NextAdl(int offset); bool HandleInputChar(char ch); + +private: + AdlInstrumentTester(const AdlInstrumentTester &); + AdlInstrumentTester &operator=(const AdlInstrumentTester &); }; #endif //ADLMIDI_HPP diff --git a/libADLMIDI-test.pro b/libADLMIDI-test.pro index bf11c1a..982a9a2 100644 --- a/libADLMIDI-test.pro +++ b/libADLMIDI-test.pro @@ -37,6 +37,7 @@ HEADERS += \ src/chips/nuked_opl3.h \ src/chips/nuked_opl3_v174.h \ src/chips/opl_chip_base.h \ + src/chips/opl_chip_base.tcc \ src/fraction.hpp \ src/midiplay/wave_writer.h @@ -57,7 +58,6 @@ SOURCES += \ src/chips/nuked/nukedopl3.c \ src/chips/nuked_opl3.cpp \ src/chips/nuked_opl3_v174.cpp \ - src/chips/opl_chip_base.cpp \ utils/midiplay/adlmidiplay.cpp \ utils/midiplay/wave_writer.c diff --git a/libADLMIDI.pro b/libADLMIDI.pro new file mode 100644 index 0000000..64c9aa1 --- /dev/null +++ b/libADLMIDI.pro @@ -0,0 +1,55 @@ +# +# Project file for the Qt Creator IDE +# + +TEMPLATE = lib +CONFIG -= qt +CONFIG += staticlib + +TARGET = ADLMIDI +INSTALLINCLUDES = $$PWD/include/* +INSTALLINCLUDESTO = ADLMIDI +include($$PWD/../audio_codec_common.pri) + +DEFINES += ADLMIDI_DISABLE_CPP_EXTRAS + +macx: QMAKE_CXXFLAGS_WARN_ON += -Wno-absolute-value + +INCLUDEPATH += $$PWD $$PWD/include + +HEADERS += \ + include/adlmidi.h \ + src/adlbank.h \ + src/adldata.hh \ + src/adlmidi_mus2mid.h \ + src/adlmidi_private.hpp \ + src/adlmidi_xmi2mid.h \ + src/wopl/wopl_file.h \ + src/chips/dosbox/dbopl.h \ + src/chips/dosbox_opl3.h \ + src/chips/nuked/nukedopl3_174.h \ + src/chips/nuked/nukedopl3.h \ + src/chips/nuked_opl3.h \ + src/chips/nuked_opl3_v174.h \ + src/chips/opl_chip_base.h \ + src/chips/opl_chip_base.tcc \ + src/fraction.hpp + +SOURCES += \ + src/adldata.cpp \ + \ + src/adlmidi.cpp \ + src/adlmidi_load.cpp \ + src/adlmidi_midiplay.cpp \ + src/adlmidi_mus2mid.c \ + src/adlmidi_opl3.cpp \ + src/adlmidi_private.cpp \ + src/adlmidi_xmi2mid.c \ + src/wopl/wopl_file.c \ + src/chips/dosbox/dbopl.cpp \ + src/chips/dosbox_opl3.cpp \ + src/chips/nuked/nukedopl3_174.c \ + src/chips/nuked/nukedopl3.c \ + src/chips/nuked_opl3.cpp \ + src/chips/nuked_opl3_v174.cpp + diff --git a/projects/watcom/ADLMIDI-linux32.tgt b/projects/watcom/ADLMIDI-linux32.tgt new file mode 100644 index 0000000..98a1799 --- /dev/null +++ b/projects/watcom/ADLMIDI-linux32.tgt @@ -0,0 +1,475 @@ +40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+3
+LIB
+3
+WString
+5
+x_2sn
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+19
+ADLMIDI-linux32.lib
+7
+WString
+3
+LIB
+8
+WVList
+2
+9
+MCState
+10
+WString
+4
+WLIB
+11
+WString
+25
+???s?Strip LINNUM records
+1
+1
+12
+MVState
+13
+WString
+4
+WLIB
+14
+WString
+16
+???s?Page bound:
+1
+15
+WString
+4
+1024
+0
+16
+WVList
+1
+17
+ActionStates
+18
+WString
+5
+&Make
+19
+WVList
+0
+-1
+1
+1
+0
+20
+WPickList
+16
+21
+MItem
+3
+*.c
+22
+WString
+4
+COBJ
+23
+WVList
+3
+24
+MVState
+25
+WString
+3
+WCC
+26
+WString
+25
+x????Include directories:
+1
+27
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+28
+MRState
+29
+WString
+3
+WCC
+30
+WString
+33
+??2??80386 register-based calling
+1
+1
+31
+MRState
+32
+WString
+3
+WCC
+33
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+34
+WVList
+1
+35
+ActionStates
+36
+WString
+5
+&Make
+37
+WVList
+0
+-1
+1
+1
+0
+38
+MItem
+27
+..\..\src\adlmidi_mus2mid.c
+39
+WString
+4
+COBJ
+40
+WVList
+0
+41
+WVList
+0
+21
+1
+1
+0
+42
+MItem
+27
+..\..\src\adlmidi_xmi2mid.c
+43
+WString
+4
+COBJ
+44
+WVList
+0
+45
+WVList
+0
+21
+1
+1
+0
+46
+MItem
+33
+..\..\src\chips\nuked\nukedopl3.c
+47
+WString
+4
+COBJ
+48
+WVList
+0
+49
+WVList
+0
+21
+1
+1
+0
+50
+MItem
+37
+..\..\src\chips\nuked\nukedopl3_174.c
+51
+WString
+4
+COBJ
+52
+WVList
+0
+53
+WVList
+0
+21
+1
+1
+0
+54
+MItem
+26
+..\..\src\wopl\wopl_file.c
+55
+WString
+4
+COBJ
+56
+WVList
+0
+57
+WVList
+0
+21
+1
+1
+0
+58
+MItem
+5
+*.cpp
+59
+WString
+6
+CPPOBJ
+60
+WVList
+4
+61
+MVState
+62
+WString
+3
+WPP
+63
+WString
+25
+x????Include directories:
+1
+64
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+65
+MVState
+66
+WString
+3
+WPP
+67
+WString
+23
+?????Macro definitions:
+1
+68
+WString
+31
+ADLMIDI_DISABLE_DOSBOX_EMULATOR
+0
+69
+MRState
+70
+WString
+3
+WPP
+71
+WString
+21
+?????Default rounding
+1
+0
+72
+MRState
+73
+WString
+3
+WPP
+74
+WString
+18
+?????Omit rounding
+1
+1
+75
+WVList
+0
+-1
+1
+1
+0
+76
+MItem
+21
+..\..\src\adldata.cpp
+77
+WString
+6
+CPPOBJ
+78
+WVList
+0
+79
+WVList
+0
+58
+1
+1
+0
+80
+MItem
+21
+..\..\src\adlmidi.cpp
+81
+WString
+6
+CPPOBJ
+82
+WVList
+0
+83
+WVList
+0
+58
+1
+1
+0
+84
+MItem
+26
+..\..\src\adlmidi_load.cpp
+85
+WString
+6
+CPPOBJ
+86
+WVList
+0
+87
+WVList
+0
+58
+1
+1
+0
+88
+MItem
+30
+..\..\src\adlmidi_midiplay.cpp
+89
+WString
+6
+CPPOBJ
+90
+WVList
+0
+91
+WVList
+0
+58
+1
+1
+0
+92
+MItem
+26
+..\..\src\adlmidi_opl3.cpp
+93
+WString
+6
+CPPOBJ
+94
+WVList
+0
+95
+WVList
+0
+58
+1
+1
+0
+96
+MItem
+29
+..\..\src\adlmidi_private.cpp
+97
+WString
+6
+CPPOBJ
+98
+WVList
+0
+99
+WVList
+0
+58
+1
+1
+0
+100
+MItem
+30
+..\..\src\chips\nuked_opl3.cpp
+101
+WString
+6
+CPPOBJ
+102
+WVList
+0
+103
+WVList
+0
+58
+1
+1
+0
+104
+MItem
+35
+..\..\src\chips\nuked_opl3_v174.cpp
+105
+WString
+6
+CPPOBJ
+106
+WVList
+0
+107
+WVList
+0
+58
+1
+1
+0
+108
+MItem
+33
+..\..\src\chips\opl_chip_base.cpp
+109
+WString
+6
+CPPOBJ
+110
+WVList
+0
+111
+WVList
+0
+58
+1
+1
+0
diff --git a/projects/watcom/ADLMIDI-win32.tgt b/projects/watcom/ADLMIDI-win32.tgt new file mode 100644 index 0000000..379bf30 --- /dev/null +++ b/projects/watcom/ADLMIDI-win32.tgt @@ -0,0 +1,475 @@ +40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+4
+NDLL
+3
+WString
+5
+n_2dn
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+17
+ADLMIDI-win32.dll
+7
+WString
+4
+NDLL
+8
+WVList
+2
+9
+MCState
+10
+WString
+4
+WLIB
+11
+WString
+25
+???s?Strip LINNUM records
+1
+1
+12
+MVState
+13
+WString
+4
+WLIB
+14
+WString
+16
+???s?Page bound:
+1
+15
+WString
+4
+1024
+0
+16
+WVList
+1
+17
+ActionStates
+18
+WString
+5
+&Make
+19
+WVList
+0
+-1
+1
+1
+0
+20
+WPickList
+16
+21
+MItem
+3
+*.c
+22
+WString
+4
+COBJ
+23
+WVList
+3
+24
+MVState
+25
+WString
+3
+WCC
+26
+WString
+25
+n????Include directories:
+1
+27
+WString
+47
+"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+0
+28
+MRState
+29
+WString
+3
+WCC
+30
+WString
+33
+??2??80386 register-based calling
+1
+1
+31
+MRState
+32
+WString
+3
+WCC
+33
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+34
+WVList
+1
+35
+ActionStates
+36
+WString
+5
+&Make
+37
+WVList
+0
+-1
+1
+1
+0
+38
+MItem
+27
+..\..\src\adlmidi_mus2mid.c
+39
+WString
+4
+COBJ
+40
+WVList
+0
+41
+WVList
+0
+21
+1
+1
+0
+42
+MItem
+27
+..\..\src\adlmidi_xmi2mid.c
+43
+WString
+4
+COBJ
+44
+WVList
+0
+45
+WVList
+0
+21
+1
+1
+0
+46
+MItem
+33
+..\..\src\chips\nuked\nukedopl3.c
+47
+WString
+4
+COBJ
+48
+WVList
+0
+49
+WVList
+0
+21
+1
+1
+0
+50
+MItem
+37
+..\..\src\chips\nuked\nukedopl3_174.c
+51
+WString
+4
+COBJ
+52
+WVList
+0
+53
+WVList
+0
+21
+1
+1
+0
+54
+MItem
+26
+..\..\src\wopl\wopl_file.c
+55
+WString
+4
+COBJ
+56
+WVList
+0
+57
+WVList
+0
+21
+1
+1
+0
+58
+MItem
+5
+*.cpp
+59
+WString
+6
+CPPOBJ
+60
+WVList
+4
+61
+MVState
+62
+WString
+3
+WPP
+63
+WString
+25
+n????Include directories:
+1
+64
+WString
+47
+"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+0
+65
+MVState
+66
+WString
+3
+WPP
+67
+WString
+23
+?????Macro definitions:
+1
+68
+WString
+31
+ADLMIDI_DISABLE_DOSBOX_EMULATOR
+0
+69
+MRState
+70
+WString
+3
+WPP
+71
+WString
+21
+?????Default rounding
+1
+0
+72
+MRState
+73
+WString
+3
+WPP
+74
+WString
+18
+?????Omit rounding
+1
+1
+75
+WVList
+0
+-1
+1
+1
+0
+76
+MItem
+21
+..\..\src\adldata.cpp
+77
+WString
+6
+CPPOBJ
+78
+WVList
+0
+79
+WVList
+0
+58
+1
+1
+0
+80
+MItem
+21
+..\..\src\adlmidi.cpp
+81
+WString
+6
+CPPOBJ
+82
+WVList
+0
+83
+WVList
+0
+58
+1
+1
+0
+84
+MItem
+26
+..\..\src\adlmidi_load.cpp
+85
+WString
+6
+CPPOBJ
+86
+WVList
+0
+87
+WVList
+0
+58
+1
+1
+0
+88
+MItem
+30
+..\..\src\adlmidi_midiplay.cpp
+89
+WString
+6
+CPPOBJ
+90
+WVList
+0
+91
+WVList
+0
+58
+1
+1
+0
+92
+MItem
+26
+..\..\src\adlmidi_opl3.cpp
+93
+WString
+6
+CPPOBJ
+94
+WVList
+0
+95
+WVList
+0
+58
+1
+1
+0
+96
+MItem
+29
+..\..\src\adlmidi_private.cpp
+97
+WString
+6
+CPPOBJ
+98
+WVList
+0
+99
+WVList
+0
+58
+1
+1
+0
+100
+MItem
+30
+..\..\src\chips\nuked_opl3.cpp
+101
+WString
+6
+CPPOBJ
+102
+WVList
+0
+103
+WVList
+0
+58
+1
+1
+0
+104
+MItem
+35
+..\..\src\chips\nuked_opl3_v174.cpp
+105
+WString
+6
+CPPOBJ
+106
+WVList
+0
+107
+WVList
+0
+58
+1
+1
+0
+108
+MItem
+33
+..\..\src\chips\opl_chip_base.cpp
+109
+WString
+6
+CPPOBJ
+110
+WVList
+0
+111
+WVList
+0
+58
+1
+1
+0
diff --git a/projects/watcom/ADLMIDI.tgt b/projects/watcom/ADLMIDI.tgt index 4c3e335..5e8def9 100644 --- a/projects/watcom/ADLMIDI.tgt +++ b/projects/watcom/ADLMIDI.tgt @@ -12,7 +12,7 @@ LIB 3
WString
5
-n_2sn
+d_2sn
1
0
1
@@ -59,7 +59,7 @@ WString 15
WString
4
-1024
+4096
0
16
WVList
@@ -79,7 +79,7 @@ WVList 0
20
WPickList
-11
+16
21
MItem
3
@@ -100,12 +100,12 @@ WCC 26
WString
25
-n????Include directories:
+d????Include directories:
1
27
WString
-46
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+30
+"$(%watcom)/h" "../../include"
0
28
MRState
@@ -185,8 +185,8 @@ WVList 0
46
MItem
-21
-..\..\src\nukedopl3.c
+33
+..\..\src\chips\nuked\nukedopl3.c
47
WString
4
@@ -203,143 +203,273 @@ WVList 0
50
MItem
+37
+..\..\src\chips\nuked\nukedopl3_174.c
+51
+WString
+4
+COBJ
+52
+WVList
+0
+53
+WVList
+0
+21
+1
+1
+0
+54
+MItem
+26
+..\..\src\wopl\wopl_file.c
+55
+WString
+4
+COBJ
+56
+WVList
+0
+57
+WVList
+0
+21
+1
+1
+0
+58
+MItem
5
*.cpp
-51
+59
WString
6
CPPOBJ
-52
+60
WVList
-1
-53
+4
+61
MVState
-54
+62
WString
3
WPP
-55
+63
WString
25
-n????Include directories:
+d????Include directories:
1
-56
+64
WString
-47
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+30
+"$(%watcom)/h" "../../include"
0
-57
+65
+MVState
+66
+WString
+3
+WPP
+67
+WString
+23
+?????Macro definitions:
+1
+68
+WString
+31
+ADLMIDI_DISABLE_DOSBOX_EMULATOR
+0
+69
+MRState
+70
+WString
+3
+WPP
+71
+WString
+21
+?????Default rounding
+1
+0
+72
+MRState
+73
+WString
+3
+WPP
+74
+WString
+18
+?????Omit rounding
+1
+1
+75
WVList
0
-1
1
1
0
-58
+76
MItem
21
..\..\src\adldata.cpp
-59
+77
WString
6
CPPOBJ
-60
+78
WVList
0
-61
+79
WVList
0
-50
+58
1
1
0
-62
+80
MItem
21
..\..\src\adlmidi.cpp
-63
+81
WString
6
CPPOBJ
-64
+82
WVList
0
-65
+83
WVList
0
-50
+58
1
1
0
-66
+84
MItem
26
..\..\src\adlmidi_load.cpp
-67
+85
WString
6
CPPOBJ
-68
+86
WVList
0
-69
+87
WVList
0
-50
+58
1
1
0
-70
+88
MItem
30
..\..\src\adlmidi_midiplay.cpp
-71
+89
WString
6
CPPOBJ
-72
+90
WVList
0
-73
+91
WVList
0
-50
+58
1
1
0
-74
+92
MItem
26
..\..\src\adlmidi_opl3.cpp
-75
+93
WString
6
CPPOBJ
-76
+94
WVList
0
-77
+95
WVList
0
-50
+58
1
1
0
-78
+96
MItem
29
..\..\src\adlmidi_private.cpp
-79
+97
WString
6
CPPOBJ
-80
+98
WVList
0
-81
+99
WVList
0
-50
+58
+1
+1
+0
+100
+MItem
+30
+..\..\src\chips\nuked_opl3.cpp
+101
+WString
+6
+CPPOBJ
+102
+WVList
+0
+103
+WVList
+0
+58
+1
+1
+0
+104
+MItem
+35
+..\..\src\chips\nuked_opl3_v174.cpp
+105
+WString
+6
+CPPOBJ
+106
+WVList
+0
+107
+WVList
+0
+58
+1
+1
+0
+108
+MItem
+33
+..\..\src\chips\opl_chip_base.cpp
+109
+WString
+6
+CPPOBJ
+110
+WVList
+0
+111
+WVList
+0
+58
1
1
0
diff --git a/projects/watcom/libADLMIDI-linux32.wpj b/projects/watcom/libADLMIDI-linux32.wpj new file mode 100644 index 0000000..e3262c6 --- /dev/null +++ b/projects/watcom/libADLMIDI-linux32.wpj @@ -0,0 +1,63 @@ +40
+projectIdent
+0
+VpeMain
+1
+WRect
+-32
+260
+10304
+9710
+2
+MProject
+3
+MCommand
+0
+4
+MCommand
+0
+2
+5
+WFileName
+19
+ADLMIDI-linux32.tgt
+6
+WFileName
+20
+playmidi-linux32.tgt
+7
+WVList
+2
+8
+VComponent
+9
+WRect
+232
+380
+5712
+4360
+0
+0
+10
+WFileName
+19
+ADLMIDI-linux32.tgt
+0
+15
+11
+VComponent
+12
+WRect
+3896
+1440
+5712
+4360
+0
+0
+13
+WFileName
+20
+playmidi-linux32.tgt
+0
+3
+11
diff --git a/projects/watcom/libADLMIDI-win32.wpj b/projects/watcom/libADLMIDI-win32.wpj new file mode 100644 index 0000000..9a7684d --- /dev/null +++ b/projects/watcom/libADLMIDI-win32.wpj @@ -0,0 +1,63 @@ +40
+projectIdent
+0
+VpeMain
+1
+WRect
+-32
+260
+10304
+9710
+2
+MProject
+3
+MCommand
+0
+4
+MCommand
+0
+2
+5
+WFileName
+17
+ADLMIDI-win32.tgt
+6
+WFileName
+18
+playmidi-win32.tgt
+7
+WVList
+2
+8
+VComponent
+9
+WRect
+560
+450
+5712
+4360
+0
+0
+10
+WFileName
+17
+ADLMIDI-win32.tgt
+0
+15
+11
+VComponent
+12
+WRect
+3392
+1430
+5712
+4360
+0
+0
+13
+WFileName
+18
+playmidi-win32.tgt
+0
+3
+11
diff --git a/projects/watcom/libADLMIDI.wpj b/projects/watcom/libADLMIDI.wpj index b7bfc41..7bdefd1 100644 --- a/projects/watcom/libADLMIDI.wpj +++ b/projects/watcom/libADLMIDI.wpj @@ -4,10 +4,10 @@ projectIdent VpeMain
1
WRect
--24
-270
-10288
-9680
+-32
+260
+10304
+9710
2
MProject
3
@@ -24,7 +24,7 @@ ADLMIDI.tgt 6
WFileName
12
-playmidi.tgt
+pmidid32.tgt
7
WVList
2
@@ -32,8 +32,8 @@ WVList VComponent
9
WRect
-160
-270
+328
+240
5712
4360
0
@@ -48,8 +48,8 @@ ADLMIDI.tgt VComponent
12
WRect
-1712
-810
+3760
+680
5712
4360
0
@@ -57,7 +57,7 @@ WRect 13
WFileName
12
-playmidi.tgt
+pmidid32.tgt
0
3
11
diff --git a/projects/watcom/playmidi-debug-crashful.zip b/projects/watcom/playmidi-debug-crashful.zip Binary files differnew file mode 100644 index 0000000..e202403 --- /dev/null +++ b/projects/watcom/playmidi-debug-crashful.zip diff --git a/projects/watcom/playmidi-linux32.tgt b/projects/watcom/playmidi-linux32.tgt new file mode 100644 index 0000000..e12f4e4 --- /dev/null +++ b/projects/watcom/playmidi-linux32.tgt @@ -0,0 +1,322 @@ +40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+3
+LNX
+3
+WString
+5
+x_2en
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+20
+playmidi-linux32.elf
+7
+WString
+3
+LNX
+8
+WVList
+1
+9
+MVState
+10
+WString
+5
+WLINK
+11
+WString
+18
+?????Libraries(,):
+1
+12
+WString
+15
+ADLMIDI-linux32
+0
+13
+WVList
+5
+14
+ActionStates
+15
+WString
+7
+Sam&ple
+16
+WVList
+0
+17
+ActionStates
+18
+WString
+13
+Remote D&ebug
+19
+WVList
+2
+20
+MRState
+21
+WString
+6
+RDEBUG
+22
+WString
+13
+????9Windowed
+1
+0
+23
+MRState
+24
+WString
+6
+RDEBUG
+25
+WString
+19
+????9Character mode
+1
+1
+26
+ActionStates
+27
+WString
+12
+Local &Debug
+28
+WVList
+1
+29
+MVState
+30
+WString
+6
+WDEBUG
+31
+WString
+28
+?????Application parameters:
+1
+32
+WString
+9
+ttd10.mid
+0
+33
+ActionStates
+34
+WString
+5
+&Make
+35
+WVList
+0
+36
+ActionStates
+37
+WString
+4
+&Run
+38
+WVList
+1
+39
+MVState
+40
+WString
+3
+RUN
+41
+WString
+28
+?????Application parameters:
+1
+42
+WString
+9
+ttd10.mid
+0
+-1
+1
+1
+0
+43
+WPickList
+4
+44
+MItem
+3
+*.c
+45
+WString
+4
+COBJ
+46
+WVList
+2
+47
+MVState
+48
+WString
+3
+WCC
+49
+WString
+25
+x????Include directories:
+1
+50
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+51
+MVState
+52
+WString
+3
+WCC
+53
+WString
+23
+?????Macro definitions:
+1
+54
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+55
+WVList
+0
+-1
+1
+1
+0
+56
+MItem
+34
+..\..\utils\midiplay\wave_writer.c
+57
+WString
+4
+COBJ
+58
+WVList
+0
+59
+WVList
+0
+44
+1
+1
+0
+60
+MItem
+5
+*.cpp
+61
+WString
+6
+CPPOBJ
+62
+WVList
+2
+63
+MVState
+64
+WString
+3
+WPP
+65
+WString
+25
+x????Include directories:
+1
+66
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+67
+MVState
+68
+WString
+3
+WPP
+69
+WString
+23
+?????Macro definitions:
+1
+70
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+71
+WVList
+0
+-1
+1
+1
+0
+72
+MItem
+36
+..\..\utils\midiplay\adlmidiplay.cpp
+73
+WString
+6
+CPPOBJ
+74
+WVList
+2
+75
+MRState
+76
+WString
+3
+WPP
+77
+WString
+33
+??2??80386 register-based calling
+1
+1
+78
+MRState
+79
+WString
+3
+WPP
+80
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+81
+WVList
+0
+60
+1
+1
+0
diff --git a/projects/watcom/playmidi-win32.tgt b/projects/watcom/playmidi-win32.tgt new file mode 100644 index 0000000..7a2b220 --- /dev/null +++ b/projects/watcom/playmidi-win32.tgt @@ -0,0 +1,306 @@ +40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+4
+NEXE
+3
+WString
+5
+nc2en
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+18
+playmidi-win32.exe
+7
+WString
+4
+NEXE
+8
+WVList
+1
+9
+MVState
+10
+WString
+7
+WINLINK
+11
+WString
+18
+?????Libraries(,):
+1
+12
+WString
+13
+ADLMIDI-win32
+0
+13
+WVList
+5
+14
+ActionStates
+15
+WString
+7
+Sam&ple
+16
+WVList
+0
+17
+ActionStates
+18
+WString
+13
+Remote D&ebug
+19
+WVList
+2
+20
+MRState
+21
+WString
+6
+RDEBUG
+22
+WString
+13
+????9Windowed
+1
+0
+23
+MRState
+24
+WString
+6
+RDEBUG
+25
+WString
+19
+????9Character mode
+1
+1
+26
+ActionStates
+27
+WString
+12
+Local &Debug
+28
+WVList
+1
+29
+MVState
+30
+WString
+6
+WDEBUG
+31
+WString
+28
+?????Application parameters:
+1
+32
+WString
+9
+ttd10.mid
+0
+33
+ActionStates
+34
+WString
+5
+&Make
+35
+WVList
+0
+36
+ActionStates
+37
+WString
+4
+&Run
+38
+WVList
+1
+39
+MVState
+40
+WString
+3
+RUN
+41
+WString
+28
+?????Application parameters:
+1
+42
+WString
+9
+ttd10.mid
+0
+-1
+1
+1
+0
+43
+WPickList
+4
+44
+MItem
+3
+*.c
+45
+WString
+4
+COBJ
+46
+WVList
+1
+47
+MVState
+48
+WString
+3
+WCC
+49
+WString
+25
+d????Include directories:
+1
+50
+WString
+31
+"$(%watcom)/h" "../../include"
+0
+51
+WVList
+0
+-1
+1
+1
+0
+52
+MItem
+34
+..\..\utils\midiplay\wave_writer.c
+53
+WString
+4
+COBJ
+54
+WVList
+0
+55
+WVList
+0
+44
+1
+1
+0
+56
+MItem
+5
+*.cpp
+57
+WString
+6
+CPPOBJ
+58
+WVList
+2
+59
+MVState
+60
+WString
+3
+WPP
+61
+WString
+25
+n????Include directories:
+1
+62
+WString
+46
+"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+0
+63
+MVState
+64
+WString
+3
+WPP
+65
+WString
+23
+?????Macro definitions:
+1
+66
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+67
+WVList
+0
+-1
+1
+1
+0
+68
+MItem
+36
+..\..\utils\midiplay\adlmidiplay.cpp
+69
+WString
+6
+CPPOBJ
+70
+WVList
+2
+71
+MRState
+72
+WString
+3
+WPP
+73
+WString
+33
+??2??80386 register-based calling
+1
+1
+74
+MRState
+75
+WString
+3
+WPP
+76
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+77
+WVList
+0
+56
+1
+1
+0
diff --git a/projects/watcom/playmidi.tgt b/projects/watcom/playmidi.tgt index d1c5b42..1d66c1b 100644 --- a/projects/watcom/playmidi.tgt +++ b/projects/watcom/playmidi.tgt @@ -7,12 +7,12 @@ MComponent 0
2
WString
-4
-NEXE
+3
+EXE
3
WString
5
-nc2en
+dr2en
1
0
1
@@ -28,143 +28,127 @@ MItem playmidi.exe
7
WString
-4
-NEXE
+3
+EXE
8
WVList
-2
+1
9
MVState
10
WString
-7
-WINLINK
+5
+WLINK
11
WString
-22
-?????Other options(,):
-1
-12
-WString
-12
-commit st=1m
-0
-13
-MVState
-14
-WString
-7
-WINLINK
-15
-WString
18
?????Libraries(,):
1
-16
+12
WString
7
ADLMIDI
0
-17
+13
WVList
5
-18
+14
ActionStates
-19
+15
WString
7
Sam&ple
-20
+16
WVList
0
-21
+17
ActionStates
-22
+18
WString
13
Remote D&ebug
-23
+19
WVList
2
-24
+20
MRState
-25
+21
WString
6
RDEBUG
-26
+22
WString
13
????9Windowed
1
0
-27
+23
MRState
-28
+24
WString
6
RDEBUG
-29
+25
WString
19
????9Character mode
1
1
-30
+26
ActionStates
-31
+27
WString
12
Local &Debug
-32
+28
WVList
1
-33
+29
MVState
-34
+30
WString
6
WDEBUG
-35
+31
WString
28
?????Application parameters:
1
-36
+32
WString
9
ttd10.mid
0
-37
+33
ActionStates
-38
+34
WString
5
&Make
-39
+35
WVList
0
-40
+36
ActionStates
-41
+37
WString
4
&Run
-42
+38
WVList
1
-43
+39
MVState
-44
+40
WString
3
RUN
-45
+41
WString
28
?????Application parameters:
1
-46
+42
WString
9
ttd10.mid
@@ -173,150 +157,150 @@ ttd10.mid 1
1
0
-47
+43
WPickList
4
-48
+44
MItem
3
*.c
-49
+45
WString
4
COBJ
-50
+46
WVList
1
-51
+47
MVState
-52
+48
WString
3
WCC
-53
+49
WString
25
-n????Include directories:
+d????Include directories:
1
-54
+50
WString
-47
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+31
+"$(%watcom)/h" "../../include"
0
-55
+51
WVList
0
-1
1
1
0
-56
+52
MItem
34
..\..\utils\midiplay\wave_writer.c
-57
+53
WString
4
COBJ
-58
+54
WVList
0
-59
+55
WVList
0
-48
+44
1
1
0
-60
+56
MItem
5
*.cpp
-61
+57
WString
6
CPPOBJ
-62
+58
WVList
2
-63
+59
MVState
-64
+60
WString
3
WPP
-65
+61
WString
25
-n????Include directories:
+d????Include directories:
1
-66
+62
WString
-47
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+30
+"$(%watcom)/h" "../../include"
0
-67
+63
MVState
-68
+64
WString
3
WPP
-69
+65
WString
23
?????Macro definitions:
1
-70
+66
WString
16
OUTPUT_WAVE_ONLY
0
-71
+67
WVList
0
-1
1
1
0
-72
+68
MItem
36
..\..\utils\midiplay\adlmidiplay.cpp
-73
+69
WString
6
CPPOBJ
-74
+70
WVList
2
-75
+71
MRState
-76
+72
WString
3
WPP
-77
+73
WString
33
??2??80386 register-based calling
1
1
-78
+74
MRState
-79
+75
WString
3
WPP
-80
+76
WString
39
??2??Pentium Pro register-based calling
1
0
-81
+77
WVList
0
-60
+56
1
1
0
diff --git a/projects/watcom/pmidid32.tgt b/projects/watcom/pmidid32.tgt new file mode 100644 index 0000000..e77f59e --- /dev/null +++ b/projects/watcom/pmidid32.tgt @@ -0,0 +1,322 @@ +40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+3
+EXE
+3
+WString
+5
+dr2en
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+12
+pmidid32.exe
+7
+WString
+3
+EXE
+8
+WVList
+2
+9
+MVState
+10
+WString
+5
+WLINK
+11
+WString
+11
+?????Stack:
+1
+12
+WString
+3
+10m
+0
+13
+MVState
+14
+WString
+5
+WLINK
+15
+WString
+18
+?????Libraries(,):
+1
+16
+WString
+7
+ADLMIDI
+0
+17
+WVList
+5
+18
+ActionStates
+19
+WString
+7
+Sam&ple
+20
+WVList
+0
+21
+ActionStates
+22
+WString
+13
+Remote D&ebug
+23
+WVList
+2
+24
+MRState
+25
+WString
+6
+RDEBUG
+26
+WString
+13
+????9Windowed
+1
+0
+27
+MRState
+28
+WString
+6
+RDEBUG
+29
+WString
+19
+????9Character mode
+1
+1
+30
+ActionStates
+31
+WString
+12
+Local &Debug
+32
+WVList
+1
+33
+MVState
+34
+WString
+6
+WDEBUG
+35
+WString
+28
+?????Application parameters:
+1
+36
+WString
+9
+ttd10.mid
+0
+37
+ActionStates
+38
+WString
+5
+&Make
+39
+WVList
+0
+40
+ActionStates
+41
+WString
+4
+&Run
+42
+WVList
+1
+43
+MVState
+44
+WString
+3
+RUN
+45
+WString
+28
+?????Application parameters:
+1
+46
+WString
+9
+ttd10.mid
+0
+-1
+1
+1
+0
+47
+WPickList
+4
+48
+MItem
+3
+*.c
+49
+WString
+4
+COBJ
+50
+WVList
+1
+51
+MVState
+52
+WString
+3
+WCC
+53
+WString
+25
+d????Include directories:
+1
+54
+WString
+31
+"$(%watcom)/h" "../../include"
+0
+55
+WVList
+0
+-1
+1
+1
+0
+56
+MItem
+34
+..\..\utils\midiplay\wave_writer.c
+57
+WString
+4
+COBJ
+58
+WVList
+0
+59
+WVList
+0
+48
+1
+1
+0
+60
+MItem
+5
+*.cpp
+61
+WString
+6
+CPPOBJ
+62
+WVList
+2
+63
+MVState
+64
+WString
+3
+WPP
+65
+WString
+25
+d????Include directories:
+1
+66
+WString
+30
+"$(%watcom)/h" "../../include"
+0
+67
+MVState
+68
+WString
+3
+WPP
+69
+WString
+23
+?????Macro definitions:
+1
+70
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+71
+WVList
+0
+-1
+1
+1
+0
+72
+MItem
+36
+..\..\utils\midiplay\adlmidiplay.cpp
+73
+WString
+6
+CPPOBJ
+74
+WVList
+2
+75
+MRState
+76
+WString
+3
+WPP
+77
+WString
+33
+??2??80386 register-based calling
+1
+1
+78
+MRState
+79
+WString
+3
+WPP
+80
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+81
+WVList
+0
+60
+1
+1
+0
diff --git a/src/adldata.cpp b/src/adldata.cpp index 4105934..49eb36c 100644 --- a/src/adldata.cpp +++ b/src/adldata.cpp @@ -4,7 +4,7 @@ * FROM A NUMBER OF SOURCES, MOSTLY PC GAMES. * PREPROCESSED, CONVERTED, AND POSTPROCESSED OFF-SCREEN. */ -const adldata adl[4532] = +const adldata adl[4535] = { // ,---------+-------- Wave select settings // | ,-------ч-+------ Sustain/release rates // | | ,-----ч-ч-+---- Attack/decay rates @@ -4172,10 +4172,10 @@ const adldata adl[4532] = { 0x332ED12,0x1E7D211, 0x80,0x45, 0x2, +0 }, { 0x0F4E431,0x0F5F331, 0x97,0x86, 0x8, +0 }, { 0x3F0F701,0x1F8F900, 0x00,0x0D, 0xE, +0 }, - { 0x0F78111,0x3F7F054, 0x40,0x45, 0x8, +0 }, - { 0x0F78140,0x3F7F040, 0x40,0x01, 0xC, +14 }, - { 0x0F78111,0x2F7F054, 0x40,0x45, 0xA, +0 }, - { 0x0F78140,0x3F7F040, 0x40,0x05, 0xC, +14 }, + { 0x0F77111,0x3F7F011, 0x48,0x87, 0xA, +0 }, + { 0x0F78140,0x3F7F040, 0x86,0x00, 0xC, +14 }, + { 0x0F78140,0x3F7F040, 0x07,0x40, 0xC, +12 }, + { 0x0F78100,0x3F7F000, 0x86,0x03, 0xC, +14 }, { 0x6F78AE8,0x649B1F4, 0x03,0x0A, 0xA, +0 }, { 0x6F78AE8,0x649B1F4, 0x43,0x4B, 0xA, +0 }, { 0x0609533,0x4E5C131, 0x63,0x05, 0x0, +0 }, @@ -4213,8 +4213,8 @@ const adldata adl[4532] = { 0x4109033,0x2044520, 0xA8,0x85, 0xA, +0 }, { 0x2034170,0x0043671, 0x08,0x20, 0x9, +0 }, { 0x1022171,0x0042671, 0x0C,0x17, 0xB, +0 }, - { 0x0055021,0x0F55022, 0x1C,0x0F, 0x7, +0 }, - { 0x0F54066,0x0F55024, 0x5A,0x0F, 0x7, -12 }, + { 0x005A061,0x0F55022, 0x69,0x06, 0x0, +0 }, + { 0x0008060,0x0F55021, 0x33,0x08, 0x0, +12 }, { 0x239B420,0x0076121, 0x50,0x05, 0x6, +0 }, { 0x139B462,0x00D7161, 0x91,0x14, 0x0, +0 }, { 0x05470F1,0x07460B1, 0x5A,0x80, 0x0, +0 }, @@ -4241,11 +4241,11 @@ const adldata adl[4532] = { 0x10B8020,0x11B6330, 0x87,0x00, 0x8, +12 }, { 0x1235031,0x0077C24, 0xC0,0x08, 0x2, +0 }, { 0x045D933,0x4076C35, 0xD0,0x26, 0x4, +0 }, - { 0x2077830,0x2076331, 0x9F,0x00, 0xA, +0 }, + { 0x6077831,0x2076331, 0x1E,0x00, 0x6, +0 }, { 0x0199031,0x01B6134, 0x95,0x80, 0xA, +0 }, { 0x0177532,0x0174531, 0x93,0x03, 0xC, +0 }, { 0x0277530,0x0174536, 0x14,0x9C, 0xE, +12 }, - { 0x08D6EF1,0x02A3571, 0xC0,0x00, 0xE, +0 }, + { 0x08B8EF1,0x0285571, 0xC0,0x00, 0xE, +0 }, { 0x08860A1,0x01A6561, 0x5C,0x00, 0x8, +0 }, { 0x2176522,0x0277421, 0x5A,0x00, 0x6, +0 }, { 0x1267532,0x0166531, 0x8D,0x05, 0x4, +0 }, @@ -4267,12 +4267,12 @@ const adldata adl[4532] = { 0x32B7420,0x12BF134, 0x46,0x00, 0x8, +0 }, { 0x5029072,0x0069061, 0x96,0x0C, 0x8, +0 }, { 0x1019031,0x0069061, 0x1A,0x0C, 0x6, +0 }, - { 0x245C224,0x2550133, 0x81,0x80, 0xB, -36 }, - { 0x2459224,0x2556133, 0x81,0x80, 0xB, -36 }, + { 0x245C224,0x2550133, 0x81,0x80, 0x9, -36 }, + { 0x2459224,0x2556133, 0x81,0x80, 0x9, -36 }, { 0x132ED10,0x3E7D010, 0x87,0x0D, 0x6, +12 }, { 0x132ED30,0x3E7D010, 0x87,0x12, 0x6, +12 }, - { 0x033513A,0x013C121, 0xA4,0x06, 0x2, +0 }, - { 0x273F325,0x0228231, 0x20,0x06, 0x4, +0 }, + { 0x073513A,0x013C121, 0xA4,0x0A, 0x2, +0 }, + { 0x273F325,0x0228231, 0x20,0x0A, 0x4, +0 }, { 0x0031131,0x0054361, 0xD4,0x08, 0x4, +0 }, { 0x20311B0,0x00543E1, 0xD9,0x08, 0x4, +0 }, { 0x245A121,0x126A121, 0x98,0x05, 0xC, +0 }, @@ -4370,16 +4370,19 @@ const adldata adl[4532] = { 0x001F312,0x047BB05, 0x03,0x07, 0xC, +12 }, { 0x0015500,0x007C71B, 0x0C,0x00, 0x0, +0 }, { 0x201F312,0x047BB09, 0x03,0x07, 0xC, +12 }, + { 0x291F108,0x333F401, 0x00,0x00, 0x8, +12 }, + { 0x291F108,0x333F501, 0x00,0x00, 0x8, +12 }, { 0x0015500,0x007C71F, 0x0C,0x00, 0x0, +0 }, - { 0x210F509,0x605FE05, 0x8A,0x8A, 0xE, +12 }, - { 0x400F509,0x605FE05, 0x07,0x8A, 0xA, +12 }, + { 0x300F50C,0x605FE05, 0x07,0x8A, 0x0, +12 }, + { 0x310F508,0x604FE05, 0x86,0x8A, 0x0, +11 }, { 0x2E1F11E,0x3F3F318, 0x04,0x00, 0x8, +0 }, { 0x2777603,0x3679601, 0x87,0x08, 0x6, +12 }, { 0x277C643,0x3679601, 0x87,0x08, 0xE, +12 }, { 0x366F905,0x099F701, 0x00,0x00, 0xC, +12 }, + { 0x291F108,0x334F401, 0x00,0x00, 0x8, +12 }, { 0x431A000,0x085B41A, 0x81,0x05, 0xA, +12 }, { 0x459F640,0x185B418, 0x00,0x20, 0xB, +12 }, - { 0x212FD08,0x305FD03, 0x01,0x03, 0x8, +12 }, + { 0x300F50C,0x605FE04, 0x07,0x8A, 0x0, +12 }, { 0x2A8F9E3,0x0779643, 0x1E,0x08, 0x2, +6 }, { 0x0A5F7E8,0x0D89949, 0xDE,0x00, 0x0, +0 }, { 0x2A8F9E3,0x0779643, 0x1E,0x00, 0xE, +12 }, @@ -4549,4681 +4552,4811 @@ const adldata adl[4532] = { 0x07BF003,0x07BF502, 0x8A,0x80, 0x8, +0 }, { 0x07BF003,0x07BF402, 0x8A,0x80, 0x8, +0 }, }; -const struct adlinsdata adlins[4673] = +const struct adlinsdata adlins[4803] = { - { 0, 0, 0, 0, 1660, 1660,0.000000 }, - { 1, 1, 0, 0, 1746, 1746,0.000000 }, - { 2, 2, 0, 0, 1980, 1980,0.000000 }, - { 3, 3, 0, 0, 1553, 1553,0.000000 }, - { 4, 4, 0, 0, 1233, 1233,0.000000 }, - { 5, 5, 0, 0, 1980, 1980,0.000000 }, - { 6, 6, 0, 0, 1100, 1100,0.000000 }, - { 7, 7, 0, 0, 1233, 1233,0.000000 }, - { 8, 8, 0, 0, 940, 940,0.000000 }, - { 9, 9, 0, 0, 1100, 1100,0.000000 }, - { 10, 10, 0, 0, 460, 460,0.000000 }, - { 11, 11, 0, 0, 1740, 1740,0.000000 }, - { 12, 12, 0, 0, 66, 66,0.000000 }, - { 13, 13, 0, 0, 140, 140,0.000000 }, - { 14, 14, 0, 0, 940, 940,0.000000 }, - { 15, 15, 0, 0, 266, 266,0.000000 }, - { 16, 16, 0, 0, 40000, 33,0.000000 }, - { 17, 17, 0, 0, 40000, 6,0.000000 }, - { 18, 18, 0, 0, 40000, 13,0.000000 }, - { 19, 19, 0, 0, 40000, 193,0.000000 }, - { 20, 20, 0, 0, 40000, 193,0.000000 }, - { 21, 21, 0, 0, 40000, 6,0.000000 }, - { 22, 22, 0, 0, 40000, 66,0.000000 }, - { 23, 23, 0, 0, 40000, 66,0.000000 }, - { 24, 24, 0, 0, 1026, 1026,0.000000 }, - { 25, 25, 0, 0, 1826, 1826,0.000000 }, - { 26, 26, 0, 0, 1813, 1813,0.000000 }, - { 27, 27, 0, 0, 1080, 1080,0.000000 }, - { 28, 28, 0, 0, 40000, 0,0.000000 }, - { 29, 29, 0, 0, 40000, 13,0.000000 }, - { 30, 30, 0, 0, 40000, 13,0.000000 }, - { 31, 31, 0, 0, 4200, 4200,0.000000 }, - { 32, 32, 0, 0, 940, 940,0.000000 }, - { 33, 33, 0, 0, 40000, 20,0.000000 }, - { 34, 34, 0, 0, 1746, 1746,0.000000 }, - { 35, 35, 0, 0, 40000, 0,0.000000 }, - { 36, 36, 0, 0, 2400, 2400,0.000000 }, - { 37, 37, 0, 0, 4166, 4166,0.000000 }, - { 38, 38, 0, 0, 1740, 1740,0.000000 }, - { 39, 39, 0, 0, 40000, 26,0.000000 }, - { 40, 40, 0, 0, 40000, 86,0.000000 }, - { 41, 41, 0, 0, 40000, 6,0.000000 }, - { 42, 42, 0, 0, 40000, 133,0.000000 }, - { 43, 43, 0, 0, 40000, 126,0.000000 }, - { 44, 44, 0, 0, 333, 333,0.000000 }, - { 45, 45, 0, 0, 940, 940,0.000000 }, - { 46, 46, 0, 0, 1046, 1046,0.000000 }, - { 47, 47, 0, 0, 40000, 33,0.000000 }, - { 48, 48, 0, 0, 1766, 13,0.000000 }, - { 49, 49, 0, 0, 40000, 220,0.000000 }, - { 50, 50, 0, 0, 40000, 153,0.000000 }, - { 51, 51, 0, 0, 40000, 146,0.000000 }, - { 52, 52, 0, 0, 2300, 2300,0.000000 }, - { 53, 53, 0, 0, 40000, 140,0.000000 }, - { 54, 54, 0, 0, 233, 233,0.000000 }, - { 55, 55, 0, 0, 40000, 6,0.000000 }, - { 56, 56, 0, 0, 40000, 6,0.000000 }, - { 57, 57, 0, 0, 40000, 6,0.000000 }, - { 58, 58, 0, 0, 40000, 6,0.000000 }, - { 59, 59, 0, 0, 40000, 6,0.000000 }, - { 60, 60, 0, 0, 40000, 0,0.000000 }, - { 61, 61, 0, 0, 40000, 26,0.000000 }, - { 62, 62, 0, 0, 40000, 0,0.000000 }, - { 63, 63, 0, 0, 40000, 6,0.000000 }, - { 64, 64, 0, 0, 40000, 20,0.000000 }, - { 65, 65, 0, 0, 40000, 20,0.000000 }, - { 66, 66, 0, 0, 40000, 0,0.000000 }, - { 67, 67, 0, 0, 40000, 6,0.000000 }, - { 68, 68, 0, 0, 3940, 3940,0.000000 }, - { 69, 69, 0, 0, 40000, 6,0.000000 }, - { 70, 70, 0, 0, 40000, 60,0.000000 }, - { 71, 71, 0, 0, 40000, 6,0.000000 }, - { 72, 72, 0, 0, 40000, 6,0.000000 }, - { 73, 73, 0, 0, 40000, 13,0.000000 }, - { 74, 74, 0, 0, 40000, 0,0.000000 }, - { 75, 75, 0, 0, 40000, 73,0.000000 }, - { 76, 76, 0, 0, 40000, 53,0.000000 }, - { 77, 77, 0, 0, 40000, 53,0.000000 }, - { 78, 78, 0, 0, 40000, 53,0.000000 }, - { 79, 79, 0, 0, 40000, 0,0.000000 }, - { 80, 80, 0, 0, 40000, 0,0.000000 }, - { 81, 81, 0, 0, 40000, 33,0.000000 }, - { 82, 82, 0, 0, 40000, 6,0.000000 }, - { 83, 83, 0, 0, 40000, 6,0.000000 }, - { 84, 84, 0, 0, 40000, 73,0.000000 }, - { 85, 85, 0, 0, 40000, 133,0.000000 }, - { 86, 86, 0, 0, 40000, 20,0.000000 }, - { 87, 87, 0, 0, 40000, 233,0.000000 }, - { 88, 88, 0, 0, 40000, 413,0.000000 }, - { 89, 89, 0, 0, 1660, 86,0.000000 }, - { 90, 90, 0, 0, 40000, 553,0.000000 }, - { 91, 91, 0, 0, 40000, 100,0.000000 }, - { 92, 92, 0, 0, 613, 13,0.000000 }, - { 93, 93, 0, 0, 40000, 126,0.000000 }, - { 94, 94, 0, 0, 40000, 53,0.000000 }, - { 95, 95, 0, 0, 993, 993,0.000000 }, - { 96, 96, 0, 0, 40000, 513,0.000000 }, - { 97, 97, 0, 0, 280, 280,0.000000 }, - { 98, 98, 0, 0, 40000, 73,0.000000 }, - { 99, 99, 0, 0, 2113, 2113,0.000000 }, - { 100, 100, 0, 0, 40000, 886,0.000000 }, - { 101, 101, 0, 0, 40000, 773,0.000000 }, - { 102, 102, 0, 0, 40000, 426,0.000000 }, - { 103, 103, 0, 0, 2413, 2413,0.000000 }, - { 104, 104, 0, 0, 1126, 1126,0.000000 }, - { 105, 105, 0, 0, 1046, 1046,0.000000 }, - { 106, 106, 0, 0, 866, 866,0.000000 }, - { 107, 107, 0, 0, 280, 280,0.000000 }, - { 108, 108, 0, 0, 40000, 6,0.000000 }, - { 109, 109, 0, 0, 40000, 113,0.000000 }, - { 110, 110, 0, 0, 40000, 6,0.000000 }, - { 111, 111, 0, 0, 1126, 1126,0.000000 }, - { 112, 112, 0, 0, 140, 140,0.000000 }, - { 113, 113, 0, 0, 246, 246,0.000000 }, - { 114, 114, 0, 0, 20, 20,0.000000 }, - { 115, 115, 0, 0, 146, 146,0.000000 }, - { 116, 116, 0, 0, 146, 146,0.000000 }, - { 117, 117, 0, 0, 340, 340,0.000000 }, - { 118, 118, 0, 0, 2280, 2280,0.000000 }, - { 119, 119, 0, 0, 286, 286,0.000000 }, - { 120, 120, 0, 0, 586, 586,0.000000 }, - { 121, 121, 0, 0, 4486, 4486,0.000000 }, - { 122, 122, 0, 0, 133, 133,0.000000 }, - { 123, 123, 0, 0, 186, 186,0.000000 }, - { 124, 124, 0, 0, 146, 146,0.000000 }, - { 125, 125, 0, 0, 40000, 113,0.000000 }, - { 126, 126, 0, 0, 140, 140,0.000000 }, - { 127, 127, 35, 0, 26, 26,0.000000 }, - { 128, 128, 52, 0, 20, 20,0.000000 }, - { 129, 129, 48, 0, 73, 73,0.000000 }, - { 130, 130, 58, 0, 40, 40,0.000000 }, - { 129, 129, 60, 0, 80, 80,0.000000 }, - { 131, 131, 47, 0, 106, 106,0.000000 }, - { 132, 132, 43, 0, 20, 20,0.000000 }, - { 131, 131, 49, 0, 146, 146,0.000000 }, - { 133, 133, 43, 0, 26, 26,0.000000 }, - { 131, 131, 51, 0, 160, 160,0.000000 }, - { 134, 134, 43, 0, 160, 160,0.000000 }, - { 131, 131, 54, 0, 140, 140,0.000000 }, - { 131, 131, 57, 0, 153, 153,0.000000 }, - { 135, 135, 72, 0, 600, 600,0.000000 }, - { 131, 131, 60, 0, 160, 160,0.000000 }, - { 136, 136, 76, 0, 513, 513,0.000000 }, - { 137, 137, 84, 0, 393, 393,0.000000 }, - { 138, 138, 36, 0, 400, 400,0.000000 }, - { 139, 139, 65, 0, 86, 86,0.000000 }, - { 140, 140, 84, 0, 406, 406,0.000000 }, - { 141, 141, 83, 0, 60, 60,0.000000 }, - { 135, 135, 84, 0, 406, 406,0.000000 }, - { 142, 142, 24, 0, 46, 46,0.000000 }, - { 136, 136, 77, 0, 500, 500,0.000000 }, - { 143, 143, 60, 0, 40, 40,0.000000 }, - { 144, 144, 65, 0, 40, 40,0.000000 }, - { 145, 145, 59, 0, 13, 13,0.000000 }, - { 146, 146, 51, 0, 46, 46,0.000000 }, - { 147, 147, 45, 0, 40, 40,0.000000 }, - { 148, 148, 71, 0, 140, 140,0.000000 }, - { 149, 149, 60, 0, 160, 160,0.000000 }, - { 150, 150, 58, 0, 153, 153,0.000000 }, - { 151, 151, 53, 0, 153, 153,0.000000 }, - { 152, 152, 64, 0, 86, 86,0.000000 }, - { 153, 153, 71, 0, 13, 13,0.000000 }, - { 154, 154, 61, 0, 313, 313,0.000000 }, - { 155, 155, 61, 0, 606, 606,0.000000 }, - { 156, 156, 44, 0, 80, 80,0.000000 }, - { 157, 157, 40, 0, 320, 320,0.000000 }, - { 158, 158, 69, 0, 20, 20,0.000000 }, - { 159, 159, 68, 0, 20, 20,0.000000 }, - { 160, 160, 63, 0, 33, 33,0.000000 }, - { 161, 161, 74, 0, 93, 93,0.000000 }, - { 162, 162, 60, 0, 353, 353,0.000000 }, - { 163, 163, 80, 0, 60, 60,0.000000 }, - { 164, 164, 64, 0, 873, 873,0.000000 }, - { 165, 165, 72, 0, 33, 33,0.000000 }, - { 166, 166, 73, 0, 286, 286,0.000000 }, - { 167, 167, 70, 0, 133, 133,0.000000 }, - { 168, 168, 68, 0, 20, 20,0.000000 }, - { 169, 169, 48, 0, 40, 40,0.000000 }, - { 131, 131, 53, 0, 126, 126,0.000000 }, - { 170, 170, 0, 0, 1020, 1020,0.000000 }, - { 171, 171, 0, 0, 40000, 0,0.000000 }, - { 172, 173, 0, 0, 1740, 1740,0.000000 }, - { 174, 175, 0, 0, 1260, 1260,0.000000 }, - { 176, 177, 0, 0, 1100, 1100,0.000000 }, - { 178, 178, 0, 0, 1100, 1100,0.000000 }, - { 179, 180, 0, 0, 726, 726,0.000000 }, - { 181, 181, 0, 0, 460, 460,0.000000 }, - { 182, 182, 0, 0, 246, 246,0.000000 }, - { 183, 184, 0, 0, 120, 120,0.000000 }, - { 185, 186, 0, 0, 840, 840,0.000000 }, - { 187, 187, 0, 0, 293, 293,0.000000 }, - { 188, 189, 0, 0, 1320, 1320,0.000000 }, - { 190, 191, 0, 0, 646, 6,0.000000 }, - { 192, 193, 0, 0, 40000, 6,0.000000 }, - { 194, 194, 0, 0, 40000, 6,0.000000 }, - { 195, 196, 0, 0, 40000, 0,0.000000 }, - { 197, 198, 0, 0, 40000, 20,0.000000 }, - { 199, 200, 0, 0, 2573, 6,0.000000 }, - { 201, 202, 0, 0, 953, 953,0.000000 }, - { 203, 204, 0, 0, 1740, 1740,0.000000 }, - { 205, 206, 0, 0, 1900, 1900,0.000000 }, - { 207, 208, 0, 0, 1986, 1986,0.000000 }, - { 209, 210, 0, 0, 760, 760,0.000000 }, - { 211, 212, 0, 0, 40000, 6,0.000000 }, - { 213, 213, 0, 0, 1613, 0,0.000000 }, - { 214, 215, 0, 0, 3260, 3260,0.000000 }, - { 216, 217, 0, 0, 360, 360,0.000000 }, - { 218, 219, 0, 0, 1020, 1020,0.000000 }, - { 220, 221, 0, 0, 2126, 2126,0.000000 }, - { 222, 223, 0, 0, 300, 13,0.000000 }, - { 224, 224, 0, 0, 1740, 1740,0.000000 }, - { 225, 226, 0, 0, 1720, 1720,0.000000 }, - { 227, 227, 0, 0, 146, 146,0.000000 }, - { 228, 228, 0, 0, 186, 40,0.000000 }, - { 229, 230, 0, 0, 40000, 46,0.000000 }, - { 231, 232, 0, 0, 40000, 66,0.000000 }, - { 233, 234, 0, 0, 40000, 266,0.000000 }, - { 235, 236, 0, 0, 160, 160,0.000000 }, - { 235, 237, 0, 0, 386, 386,0.000000 }, - { 46, 238, 0, 0, 1046, 1046,0.000000 }, - { 239, 240, 0, 0, 40000, 66,0.000000 }, - { 241, 242, 0, 0, 720, 46,0.000000 }, - { 243, 243, 0, 0, 40000, 33,0.000000 }, - { 244, 244, 0, 0, 40000, 6,0.000000 }, - { 245, 245, 0, 0, 40000, 13,0.000000 }, - { 246, 247, 0, 0, 466, 466,0.000000 }, - { 248, 249, 0, 0, 1213, 13,0.000000 }, - { 250, 250, 0, 0, 60, 6,0.000000 }, - { 251, 251, 0, 0, 40000, 66,0.000000 }, - { 252, 253, 0, 0, 40000, 6,0.000000 }, - { 254, 255, 0, 0, 40000, 26,0.000000 }, - { 256, 257, 0, 0, 166, 0,0.000000 }, - { 258, 259, 0, 0, 40000, 6,0.000000 }, - { 260, 261, 0, 0, 40000, 20,0.000000 }, - { 262, 263, 0, 0, 40000, 26,0.000000 }, - { 264, 265, 0, 0, 40000, 40,0.000000 }, - { 266, 267, 0, 0, 40000, 6,0.000000 }, - { 268, 269, 0, 0, 40000, 20,0.000000 }, - { 270, 271, 0, 0, 40000, 13,0.000000 }, - { 272, 273, 0, 0, 40000, 60,0.000000 }, - { 274, 275, 0, 0, 40000, 33,0.000000 }, - { 276, 276, 0, 0, 40000, 20,0.000000 }, - { 277, 278, 0, 0, 40000, 73,0.000000 }, - { 279, 280, 0, 0, 40000, 33,0.000000 }, - { 281, 282, 0, 0, 40000, 73,0.000000 }, - { 283, 283, 0, 0, 40000, 13,0.000000 }, - { 284, 285, 0, 0, 40000, 6,0.000000 }, - { 286, 287, 0, 0, 40000, 20,0.000000 }, - { 288, 288, 0, 0, 40000, 33,0.000000 }, - { 289, 290, 0, 0, 40000, 6,0.000000 }, - { 291, 292, 0, 0, 40000, 73,0.000000 }, - { 293, 294, 0, 0, 40000, 106,0.000000 }, - { 295, 296, 0, 0, 40000, 180,0.000000 }, - { 88, 297, 0, 0, 40000, 500,0.000000 }, - { 298, 299, 0, 0, 40000, 26,0.000000 }, - { 300, 301, 0, 0, 40000, 553,0.000000 }, - { 302, 302, 0, 0, 40000, 126,0.000000 }, - { 303, 303, 0, 0, 40000, 53,0.000000 }, - { 304, 304, 0, 0, 1793, 1793,0.000000 }, - { 305, 306, 0, 0, 40000, 300,0.000000 }, - { 307, 307, 0, 0, 1900, 1900,0.000000 }, - { 308, 308, 0, 0, 146, 146,0.000000 }, - { 309, 309, 0, 0, 40000, 580,0.000000 }, - { 310, 310, 0, 0, 40000, 480,0.000000 }, - { 311, 312, 0, 0, 2273, 2273,0.000000 }, - { 313, 314, 0, 0, 1140, 1140,0.000000 }, - { 315, 316, 0, 0, 560, 560,0.000000 }, - { 317, 318, 0, 0, 1080, 1080,0.000000 }, - { 107, 319, 0, 0, 280, 280,0.000000 }, - { 108, 320, 0, 0, 40000, 6,0.000000 }, - { 109, 321, 0, 0, 40000, 46,0.000000 }, - { 322, 323, 0, 0, 40000, 6,0.000000 }, - { 324, 325, 0, 0, 146, 146,0.000000 }, - { 326, 327, 0, 0, 246, 246,0.000000 }, - { 328, 328, 0, 0, 26, 26,0.000000 }, - { 329, 329, 0, 0, 140, 140,0.000000 }, - { 330, 331, 0, 0, 40, 40,0.000000 }, - { 332, 332, 0, 0, 2313, 2313,0.000000 }, - { 333, 333, 0, 0, 86, 86,0.000000 }, - { 334, 334, 0, 0, 3440, 3440,0.000000 }, - { 335, 335, 0, 0, 146, 146,0.000000 }, - { 336, 336, 0, 0, 2406, 2406,0.000000 }, - { 337, 337, 0, 0, 40000, 146,0.000000 }, - { 338, 339, 0, 0, 40000, 113,0.000000 }, - { 340, 341, 0, 0, 40000, 0,0.000000 }, - { 342, 342, 35, 0, 446, 446,0.000000 }, - { 343, 343, 0, 0, 20, 20,0.000000 }, - { 344, 344, 35, 0, 86, 86,0.000000 }, - { 345, 345, 35, 0, 26, 26,0.000000 }, - { 346, 346, 50, 0, 153, 153,0.000000 }, - { 347, 347, 18, 0, 53, 53,0.000000 }, - { 348, 348, 72, 0, 53, 53,0.000000 }, - { 349, 349, 74, 0, 33, 33,0.000000 }, - { 350, 350, 35, 0, 66, 66,0.000000 }, - { 351, 351, 16, 0, 86, 86,0.000000 }, - { 352, 352, 0, 0, 1513, 13,0.000000 }, - { 353, 353, 38, 0, 53, 53,0.000000 }, - { 354, 354, 38, 0, 100, 100,0.000000 }, - { 355, 355, 31, 0, 33, 33,0.000000 }, - { 355, 355, 35, 0, 33, 33,0.000000 }, - { 355, 355, 38, 0, 193, 193,0.000000 }, - { 355, 355, 41, 0, 166, 166,0.000000 }, - { 355, 355, 45, 0, 126, 126,0.000000 }, - { 355, 355, 50, 0, 146, 146,0.000000 }, - { 356, 356, 36, 0, 100, 100,0.000000 }, - { 357, 357, 36, 0, 26, 26,0.000000 }, - { 358, 358, 48, 0, 73, 73,0.000000 }, - { 358, 358, 36, 0, 100, 100,0.000000 }, - { 359, 359, 36, 0, 20, 20,0.000000 }, - { 360, 360, 0, 0, 33, 33,0.000000 }, - { 361, 361, 61, 0, 60, 60,0.000000 }, - { 362, 362, 96, 0, 233, 233,0.000000 }, - { 363, 363, 38, 0, 60, 60,0.000000 }, - { 127, 127, 16, 0, 66, 66,0.000000 }, - { 364, 365, 18, 0, 13, 13,0.000000 }, - { 366, 366, 30, 0, 106, 106,0.000000 }, - { 367, 368, 35, 0, 73, 73,0.000000 }, - { 129, 129, 0, 0, 73, 73,0.000000 }, - { 369, 369, 0, 0, 66, 66,0.000000 }, - { 370, 370, 88, 0, 86, 86,0.000000 }, - { 371, 371, 88, 0, 60, 60,0.000000 }, - { 372, 372, 79, 0, 380, 380,0.000000 }, - { 135, 135, 14, 0, 860, 860,0.000000 }, - { 373, 373, 46, 0, 313, 313,0.000000 }, - { 374, 375,129, 0, 1613, 60,0.000000 }, - { 376, 376, 58, 0, 140, 140,0.000000 }, - { 377, 377,164, 0, 106, 106,0.000000 }, - { 378, 378,142, 0, 2300, 2300,0.000000 }, - { 379, 379, 9, 0, 40, 40,0.000000 }, - { 380, 381, 35, 0, 3306, 0,0.000000 }, - { 382, 382, 28, 0, 26, 26,0.000000 }, - { 383, 383, 46, 0, 320, 320,0.000000 }, - { 384, 384, 60, 0, 93, 93,0.000000 }, - { 384, 384, 54, 0, 100, 100,0.000000 }, - { 385, 385, 72, 0, 60, 60,0.000000 }, - { 385, 385, 67, 0, 60, 60,0.000000 }, - { 385, 385, 60, 0, 53, 53,0.000000 }, - { 386, 386, 1, 0, 46, 46,0.000000 }, - { 387, 387, 77, 0, 133, 133,0.000000 }, - { 387, 387, 72, 0, 133, 133,0.000000 }, - { 388, 388, 90, 0, 46, 46,0.000000 }, - { 389, 389, 39, 0, 180, 180,0.000000 }, - { 390, 390, 36, 0, 506, 506,0.000000 }, - { 391, 392, 35, 0, 20, 20,0.000000 }, - { 391, 393, 35, 0, 20, 20,0.000000 }, - { 394, 394, 60, 0, 40, 40,0.000000 }, - { 328, 328, 7, 0, 26, 26,0.000000 }, - { 395, 395, 90, 0, 80, 80,0.000000 }, - { 396, 396, 90, 0, 306, 306,0.000000 }, - { 397, 397, 35, 0, 106, 106,0.000000 }, - { 398, 399, 5, 0, 506, 506,0.000000 }, - { 400, 400,103, 0, 220, 220,0.000000 }, - { 401, 401, 3, 0, 6, 6,0.000000 }, - { 169, 169, 1, 0, 40, 40,0.000000 }, - { 131, 131, 0, 0, 40, 40,0.000000 }, - { 402, 402, 36, 0, 180, 180,0.000000 }, - { 403, 403, 60, 0, 40000, 0,0.000000 }, - { 404, 404, 37, 0, 60, 60,0.000000 }, - { 405, 405, 36, 0, 46, 46,0.000000 }, - { 406, 406, 32, 0, 40, 40,0.000000 }, - { 407, 407, 50, 0, 306, 306,0.000000 }, - { 408, 408, 50, 0, 93, 93,0.000000 }, - { 409, 409, 83, 0, 26, 26,0.000000 }, - { 410, 410, 72, 0, 93, 93,0.000000 }, - { 148, 148, 59, 0, 153, 153,0.000000 }, - { 411, 411, 64, 0, 40, 40,0.000000 }, - { 411, 411, 60, 0, 40, 40,0.000000 }, - { 412, 412, 72, 0, 26, 26,0.000000 }, - { 412, 412, 62, 0, 33, 33,0.000000 }, - { 413, 413, 83, 0, 273, 273,0.000000 }, - { 414, 414, 0, 0, 40000, 13,0.000000 }, - { 415, 415, 0, 0, 1126, 1126,0.000000 }, - { 416, 416, 0, 0, 40000, 20,0.000000 }, - { 417, 417, 0, 0, 2940, 20,0.000000 }, - { 418, 418, 0, 0, 2233, 2233,0.000000 }, - { 419, 419, 0, 0, 1233, 1233,0.000000 }, - { 420, 420, 0, 0, 940, 940,0.000000 }, - { 421, 421, 0, 0, 1580, 1580,0.000000 }, - { 422, 422, 0, 0, 1740, 1740,0.000000 }, - { 423, 423, 0, 0, 140, 140,0.000000 }, - { 424, 424, 0, 0, 940, 940,0.000000 }, - { 425, 425, 0, 0, 1080, 1080,0.000000 }, - { 426, 426, 0, 0, 2086, 2086,0.000000 }, - { 427, 427, 0, 0, 40000, 26,0.000000 }, - { 428, 428, 60, 0, 40000, 0,0.000000 }, - { 429, 429, 73, 0, 473, 473,0.000000 }, - { 429, 429, 74, 0, 473, 473,0.000000 }, - { 429, 429, 80, 0, 473, 473,0.000000 }, - { 429, 429, 84, 0, 473, 473,0.000000 }, - { 429, 429, 92, 0, 400, 400,0.000000 }, - { 430, 430, 81, 0, 280, 280,0.000000 }, - { 430, 430, 83, 0, 280, 280,0.000000 }, - { 430, 430, 95, 0, 220, 220,0.000000 }, - { 431, 431, 35, 0, 46, 46,0.000000 }, - { 432, 432, 60, 0, 40, 40,0.000000 }, - { 357, 357, 59, 0, 13, 13,0.000000 }, - { 432, 432, 44, 0, 40, 40,0.000000 }, - { 433, 433, 41, 0, 166, 166,0.000000 }, - { 434, 434, 97, 0, 26, 26,0.000000 }, - { 433, 433, 44, 0, 140, 140,0.000000 }, - { 433, 433, 48, 0, 153, 153,0.000000 }, - { 435, 435, 96, 0, 233, 233,0.000000 }, - { 433, 433, 51, 0, 160, 160,0.000000 }, - { 433, 433, 54, 0, 160, 160,0.000000 }, - { 436, 436, 40, 0, 386, 386,0.000000 }, - { 433, 433, 57, 0, 113, 113,0.000000 }, - { 437, 437, 58, 0, 120, 120,0.000000 }, - { 438, 438, 97, 0, 73, 73,0.000000 }, - { 439, 439, 50, 0, 60, 60,0.000000 }, - { 437, 437, 60, 0, 153, 153,0.000000 }, - { 440, 440, 53, 0, 53, 53,0.000000 }, - { 441, 441, 46, 0, 46, 46,0.000000 }, - { 440, 440, 57, 0, 53, 53,0.000000 }, - { 442, 442, 42, 0, 206, 206,0.000000 }, - { 442, 442, 37, 0, 206, 206,0.000000 }, - { 443, 443, 41, 0, 193, 193,0.000000 }, - { 443, 443, 37, 0, 193, 193,0.000000 }, - { 444, 444, 77, 0, 46, 46,0.000000 }, - { 444, 444, 72, 0, 46, 46,0.000000 }, - { 445, 445, 70, 0, 60, 60,0.000000 }, - { 445, 445, 90, 0, 60, 60,0.000000 }, - { 446, 446, 46, 0, 46, 46,0.000000 }, - { 447, 447, 48, 0, 246, 246,0.000000 }, - { 448, 448, 85, 0, 20, 20,0.000000 }, - { 449, 449, 66, 0, 60, 60,0.000000 }, - { 449, 449, 61, 0, 60, 60,0.000000 }, - { 450, 450, 41, 0, 106, 106,0.000000 }, - { 451, 451, 41, 0, 140, 140,0.000000 }, - { 452, 452, 81, 0, 66, 66,0.000000 }, - { 400, 400, 81, 0, 266, 266,0.000000 }, - { 400, 400, 76, 0, 266, 266,0.000000 }, - { 359, 359, 60, 0, 13, 13,0.000000 }, - { 453, 453, 53, 0, 120, 120,0.000000 }, - { 454, 454, 0, 0, 40000, 0,0.000000 }, - { 455, 455, 0, 0, 40, 40,0.000000 }, - { 456, 456, 0, 0, 1080, 1080,0.000000 }, - { 457, 457, 0, 0, 126, 126,0.000000 }, - { 458, 458, 0, 0, 40000, 26,0.000000 }, - { 459, 459, 0, 0, 40000, 6,0.000000 }, - { 460, 460, 0, 0, 700, 700,0.000000 }, - { 461, 461, 0, 0, 280, 280,0.000000 }, - { 462, 462, 0, 0, 360, 360,0.000000 }, - { 463, 463, 0, 0, 40000, 20,0.000000 }, - { 464, 464, 0, 0, 1466, 13,0.000000 }, - { 465, 465, 0, 0, 40000, 33,0.000000 }, - { 466, 466, 0, 0, 40000, 33,0.000000 }, - { 467, 467, 0, 0, 1953, 1953,0.000000 }, - { 468, 468, 0, 0, 1580, 1580,0.000000 }, - { 469, 469, 0, 0, 1340, 1340,0.000000 }, - { 470, 470, 0, 0, 40000, 0,0.000000 }, - { 471, 471, 0, 0, 40000, 53,0.000000 }, - { 472, 472, 0, 0, 1386, 1386,0.000000 }, - { 473, 473, 0, 0, 560, 13,0.000000 }, - { 474, 474, 0, 0, 40000, 66,0.000000 }, - { 475, 475, 0, 0, 593, 593,0.000000 }, - { 476, 476, 0, 0, 40000, 2446,0.000000 }, - { 477, 477, 0, 0, 60, 60,0.000000 }, - { 478, 478, 0, 0, 220, 220,0.000000 }, - { 479, 479, 0, 0, 153, 153,0.000000 }, - { 480, 480, 0, 0, 20, 20,0.000000 }, - { 481, 481, 0, 0, 40000, 0,0.000000 }, - { 482, 482, 0, 0, 753, 753,0.000000 }, - { 483, 483, 0, 0, 100, 100,0.000000 }, - { 484, 484, 0, 0, 40000, 73,0.000000 }, - { 485, 485, 0, 0, 2600, 320,0.000000 }, - { 486, 486, 0, 0, 293, 293,0.000000 }, - { 487, 487, 0, 0, 1400, 1400,0.000000 }, - { 488, 488, 0, 0, 2073, 2073,0.000000 }, - { 489, 489, 0, 0, 80, 80,0.000000 }, - { 490, 490, 0, 0, 40000, 33,0.000000 }, - { 491, 491, 50, 0, 446, 446,0.000000 }, - { 492, 492, 37, 0, 46, 46,0.000000 }, - { 493, 493, 39, 0, 180, 180,0.000000 }, - { 494, 494, 39, 0, 33, 33,0.000000 }, - { 495, 495, 86, 0, 1800, 1800,0.000000 }, - { 496, 496, 43, 0, 33, 33,0.000000 }, - { 127, 127, 24, 0, 46, 46,0.000000 }, - { 127, 127, 29, 0, 33, 33,0.000000 }, - { 497, 497, 50, 0, 153, 153,0.000000 }, - { 498, 498, 30, 0, 100, 100,0.000000 }, - { 498, 498, 33, 0, 413, 413,0.000000 }, - { 498, 498, 38, 0, 1633, 1633,0.000000 }, - { 498, 498, 42, 0, 26, 26,0.000000 }, - { 499, 499, 24, 0, 46, 46,0.000000 }, - { 499, 499, 27, 0, 66, 66,0.000000 }, - { 499, 499, 29, 0, 66, 66,0.000000 }, - { 499, 499, 32, 0, 53, 53,0.000000 }, - { 500, 500, 32, 0, 13, 13,0.000000 }, - { 501, 501, 53, 0, 86, 86,0.000000 }, - { 501, 501, 57, 0, 86, 86,0.000000 }, - { 502, 502, 60, 0, 80, 80,0.000000 }, - { 503, 503, 55, 0, 160, 160,0.000000 }, - { 486, 486, 85, 0, 266, 266,0.000000 }, - { 504, 504, 90, 0, 453, 453,0.000000 }, - { 505, 505, 84, 0, 73, 73,0.000000 }, - { 506, 506, 48, 0, 160, 160,0.000000 }, - { 507, 507, 48, 0, 40, 40,0.000000 }, - { 132, 132, 72, 0, 13, 13,0.000000 }, - { 508, 508, 72, 0, 13, 13,0.000000 }, - { 509, 509, 72, 0, 13, 13,0.000000 }, - { 510, 510, 63, 0, 533, 533,0.000000 }, - { 510, 510, 65, 0, 526, 526,0.000000 }, - { 511, 511, 79, 0, 506, 506,0.000000 }, - { 512, 512, 38, 0, 113, 113,0.000000 }, - { 513, 513, 94, 0, 100, 100,0.000000 }, - { 514, 514, 87, 0, 113, 113,0.000000 }, - { 514, 514, 94, 0, 100, 100,0.000000 }, - { 515, 515, 80, 0, 66, 66,0.000000 }, - { 516, 516, 47, 0, 140, 140,0.000000 }, - { 517, 517, 61, 0, 80, 80,0.000000 }, - { 517, 517, 68, 0, 66, 66,0.000000 }, - { 518, 518, 61, 0, 160, 160,0.000000 }, - { 518, 518, 68, 0, 126, 126,0.000000 }, - { 499, 499, 60, 0, 46, 46,0.000000 }, - { 519, 519, 60, 0, 60, 60,0.000000 }, - { 520, 520, 36, 0, 53, 53,0.000000 }, - { 520, 520, 60, 0, 40, 40,0.000000 }, - { 521, 521, 60, 0, 40, 40,0.000000 }, - { 522, 522, 68, 0, 20, 20,0.000000 }, - { 523, 523, 71, 0, 33, 33,0.000000 }, - { 523, 523, 72, 0, 33, 33,0.000000 }, - { 524, 524,101, 0, 320, 320,0.000000 }, - { 525, 525, 36, 0, 1680, 1680,0.000000 }, - { 526, 526, 25, 0, 40000, 2286,0.000000 }, - { 527, 527, 37, 0, 400, 400,0.000000 }, - { 528, 528, 36, 0, 146, 146,0.000000 }, - { 528, 528, 41, 0, 166, 166,0.000000 }, - { 529, 529, 84, 0, 73, 73,0.000000 }, - { 530, 530, 54, 0, 1326, 1326,0.000000 }, - { 481, 481, 48, 0, 40000, 0,0.000000 }, - { 531, 531, 0, 0, 2266, 2266,0.000000 }, - { 532, 532, 0, 0, 833, 833,0.000000 }, - { 533, 533, 0, 0, 246, 13,0.000000 }, - { 534, 534, 0, 0, 40000, 6,0.000000 }, - { 535, 535, 0, 0, 4140, 26,0.000000 }, - { 536, 536, 0, 0, 3886, 13,0.000000 }, - { 537, 537, 0, 0, 4886, 4886,0.000000 }, - { 538, 538, 0, 0, 1780, 1780,0.000000 }, - { 539, 539, 0, 0, 4140, 26,0.000000 }, - { 540, 540, 0, 0, 40000, 6,0.000000 }, - { 541, 541, 0, 0, 3946, 13,0.000000 }, - { 542, 542, 0, 0, 40, 40,0.000000 }, - { 543, 543, 0, 0, 40000, 13,0.000000 }, - { 544, 544, 0, 0, 4426, 4426,0.000000 }, - { 545, 545, 0, 0, 40000, 493,0.000000 }, - { 546, 546, 0, 0, 40000, 846,0.000000 }, - { 547, 547, 0, 0, 40000, 53,0.000000 }, - { 135, 135, 49, 0, 1146, 1146,0.000000 }, - { 548, 548, 35, 0, 40, 40,0.000000 }, - { 549, 549, 41, 0, 6, 6,0.000000 }, - { 366, 366, 38, 0, 106, 106,0.000000 }, - { 550, 550, 39, 0, 26, 26,0.000000 }, - { 551, 551, 49, 0, 46, 46,0.000000 }, - { 408, 408, 59, 0, 93, 93,0.000000 }, - { 552, 552, 24, 0, 26, 26,0.000000 }, - { 552, 552, 27, 0, 40, 20,0.000000 }, - { 552, 552, 29, 0, 20, 20,0.000000 }, - { 552, 552, 32, 0, 40, 13,0.000000 }, - { 553, 553, 84, 0, 113, 113,0.000000 }, - { 512, 512, 79, 0, 73, 73,0.000000 }, - { 554, 554, 61, 0, 173, 173,0.000000 }, - { 554, 554, 68, 0, 133, 133,0.000000 }, - { 555, 555, 36, 0, 33, 33,0.000000 }, - { 555, 555, 60, 0, 20, 20,0.000000 }, - { 556, 556, 36, 0, 180, 180,0.000000 }, - { 115, 115, 37, 0, 46, 46,0.000000 }, - { 557, 557, 0, 0, 1066, 1066,0.000000 }, - { 558, 558, 0, 0, 273, 273,0.000000 }, - { 559, 559, 0, 0, 186, 186,0.000000 }, - { 560, 560, 0, 0, 966, 966,0.000000 }, - { 561, 561, 0, 0, 80, 80,0.000000 }, - { 562, 562, 0, 0, 326, 326,0.000000 }, - { 563, 563, 0, 0, 40000, 33,0.000000 }, - { 564, 564, 0, 0, 380, 380,0.000000 }, - { 565, 565, 0, 0, 40, 40,0.000000 }, - { 566, 566, 0, 0, 4586, 4586,0.000000 }, - { 567, 567, 0, 0, 2680, 2680,0.000000 }, - { 568, 568, 0, 0, 40000, 6,0.000000 }, - { 569, 569, 0, 0, 80, 80,0.000000 }, - { 570, 570, 0, 0, 1206, 1206,0.000000 }, - { 571, 571, 0, 0, 593, 593,0.000000 }, - { 572, 572, 0, 0, 680, 680,0.000000 }, - { 356, 356, 0, 0, 246, 246,0.000000 }, - { 573, 573, 0, 0, 40000, 20,0.000000 }, - { 574, 574, 0, 0, 40000, 20,0.000000 }, - { 575, 575, 0, 0, 40000, 73,0.000000 }, - { 576, 576, 0, 0, 40000, 53,0.000000 }, - { 577, 577, 0, 0, 40000, 33,0.000000 }, - { 578, 578, 0, 0, 40000, 140,0.000000 }, - { 579, 579, 0, 0, 40000, 93,0.000000 }, - { 580, 580, 0, 0, 40000, 126,0.000000 }, - { 581, 581, 0, 0, 40000, 26,0.000000 }, - { 582, 582, 0, 0, 40000, 53,0.000000 }, - { 583, 583, 0, 0, 513, 513,0.000000 }, - { 584, 584, 0, 0, 40000, 66,0.000000 }, - { 585, 585, 0, 0, 313, 313,0.000000 }, - { 516, 516, 0, 0, 140, 140,0.000000 }, - { 586, 586, 0, 0, 40000, 0,0.000000 }, - { 587, 587, 0, 0, 40000, 0,0.000000 }, - { 588, 588, 0, 0, 40000, 6,0.000000 }, - { 498, 498, 26, 0, 86, 86,0.000000 }, - { 494, 494, 35, 0, 53, 53,0.000000 }, - { 350, 350, 41, 0, 80, 80,0.000000 }, - { 353, 353, 48, 0, 40, 40,0.000000 }, - { 354, 354, 67, 0, 73, 73,0.000000 }, - { 502, 502, 24, 0, 100, 100,0.000000 }, - { 346, 346, 36, 0, 46, 46,0.000000 }, - { 346, 346, 38, 0, 193, 193,0.000000 }, - { 346, 346, 40, 0, 140, 140,0.000000 }, - { 346, 346, 42, 0, 173, 173,0.000000 }, - { 346, 346, 44, 0, 140, 140,0.000000 }, - { 510, 510, 55, 0, 453, 453,0.000000 }, - { 346, 346, 46, 0, 146, 146,0.000000 }, - { 136, 136, 80, 0, 486, 486,0.000000 }, - { 486, 486, 24, 0, 346, 346,0.000000 }, - { 153, 153, 50, 0, 13, 13,0.000000 }, - { 346, 346, 24, 0, 66, 66,0.000000 }, - { 516, 516, 31, 0, 186, 186,0.000000 }, - { 498, 498, 35, 0, 40, 40,0.000000 }, - { 517, 517, 60, 0, 80, 80,0.000000 }, - { 530, 530, 36, 0, 1760, 1760,0.000000 }, - { 530, 530, 48, 0, 1360, 6,0.000000 }, - { 589, 589, 0, 0, 1660, 1660,0.000000 }, - { 139, 139, 76, 0, 73, 73,0.000000 }, - { 156, 156, 48, 0, 80, 80,0.000000 }, - { 157, 157, 48, 0, 226, 226,0.000000 }, - { 165, 165, 69, 0, 40, 40,0.000000 }, - { 167, 167, 75, 0, 133, 133,0.000000 }, - { 590, 590, 0, 0, 1226, 1226,0.000000 }, - { 591, 591, 0, 0, 2193, 2193,0.000000 }, - { 592, 592, 0, 0, 1900, 1900,0.000000 }, - { 593, 593, 0, 0, 626, 626,0.000000 }, - { 594, 594, 0, 0, 1213, 1213,0.000000 }, - { 595, 595, 0, 0, 1740, 1740,0.000000 }, - { 596, 596, 0, 0, 193, 193,0.000000 }, - { 597, 597, 0, 0, 300, 300,0.000000 }, - { 598, 598, 0, 0, 40000, 6,0.000000 }, - { 599, 599, 0, 0, 40000, 480,0.000000 }, - { 600, 600, 0, 0, 40000, 20,0.000000 }, - { 601, 601, 0, 0, 653, 653,0.000000 }, - { 602, 602, 0, 0, 126, 126,0.000000 }, - { 603, 603, 0, 0, 1080, 1080,0.000000 }, - { 604, 604, 0, 0, 4200, 4200,0.000000 }, - { 605, 605, 0, 0, 1020, 1020,0.000000 }, - { 606, 606, 0, 0, 593, 13,0.000000 }, - { 607, 607, 0, 0, 80, 60,0.000000 }, - { 608, 608, 0, 0, 40000, 113,0.000000 }, - { 609, 609, 0, 0, 120, 120,0.000000 }, - { 610, 610, 0, 0, 1580, 1580,0.000000 }, - { 611, 611, 0, 0, 460, 460,0.000000 }, - { 612, 612, 0, 0, 40000, 53,0.000000 }, - { 613, 613, 0, 0, 2320, 13,0.000000 }, - { 614, 614, 0, 0, 80, 60,0.000000 }, - { 615, 615, 0, 0, 80, 60,0.000000 }, - { 616, 616, 0, 0, 1020, 1020,0.000000 }, - { 617, 617, 0, 0, 146, 146,0.000000 }, - { 618, 618, 0, 0, 740, 740,0.000000 }, - { 619, 619, 0, 0, 146, 146,0.000000 }, - { 620, 620, 0, 0, 40000, 6,0.000000 }, - { 621, 621, 0, 0, 913, 913,0.000000 }, - { 622, 622, 0, 0, 2280, 2280,0.000000 }, - { 623, 623, 0, 0, 166, 6,0.000000 }, - { 624, 624, 0, 0, 40000, 0,0.000000 }, - { 625, 625, 0, 0, 40000, 0,0.000000 }, - { 626, 626, 0, 0, 40000, 0,0.000000 }, - { 627, 627, 0, 0, 1046, 1046,0.000000 }, - { 628, 628, 0, 0, 40000, 6,0.000000 }, - { 629, 629, 0, 0, 40000, 0,0.000000 }, - { 630, 630, 0, 0, 1953, 1953,0.000000 }, - { 631, 631, 0, 0, 40000, 106,0.000000 }, - { 632, 632, 0, 0, 533, 13,0.000000 }, - { 633, 633, 0, 0, 2273, 2273,0.000000 }, - { 634, 634, 0, 0, 646, 646,0.000000 }, - { 635, 635, 0, 0, 166, 166,0.000000 }, - { 636, 636, 0, 0, 326, 326,0.000000 }, - { 637, 637, 0, 0, 40000, 26,0.000000 }, - { 638, 638, 0, 0, 246, 246,0.000000 }, - { 346, 346, 0, 0, 140, 140,0.000000 }, - { 639, 639, 0, 0, 1226, 1226,0.000000 }, - { 404, 404, 0, 0, 146, 146,0.000000 }, - { 506, 506, 0, 0, 153, 153,0.000000 }, - { 639, 639, 60, 0, 886, 886,0.000000 }, - { 639, 639, 79, 0, 446, 446,0.000000 }, - { 640, 640, 65, 0, 800, 800,0.000000 }, - { 486, 486, 31, 0, 353, 353,0.000000 }, - { 486, 486, 36, 0, 360, 360,0.000000 }, - { 640, 640, 72, 0, 613, 613,0.000000 }, - { 136, 136, 79, 0, 493, 493,0.000000 }, - { 148, 148, 57, 0, 160, 160,0.000000 }, - { 150, 150, 53, 0, 153, 153,0.000000 }, - { 641, 641, 84, 0, 106, 106,0.000000 }, - { 520, 520, 66, 0, 40, 40,0.000000 }, - { 642, 642, 31, 0, 166, 13,0.000000 }, - { 642, 642, 29, 0, 60, 26,0.000000 }, - { 356, 356, 31, 0, 93, 93,0.000000 }, - { 356, 356, 19, 0, 220, 220,0.000000 }, - { 643, 643, 31, 0, 40000, 6,0.000000 }, - { 643, 643, 29, 0, 40000, 6,0.000000 }, - { 644, 644, 31, 0, 560, 560,0.000000 }, - { 644, 644, 35, 0, 573, 573,0.000000 }, - { 644, 644, 40, 0, 526, 526,0.000000 }, - { 644, 644, 47, 0, 540, 540,0.000000 }, - { 516, 516, 32, 0, 186, 186,0.000000 }, - { 516, 516, 43, 0, 146, 146,0.000000 }, - { 495, 495, 26, 0, 60, 60,0.000000 }, - { 495, 495, 44, 0, 380, 380,0.000000 }, - { 496, 496, 26, 0, 26, 26,0.000000 }, - { 496, 496, 51, 0, 40, 40,0.000000 }, - { 496, 496, 39, 0, 33, 33,0.000000 }, - { 495, 495, 30, 0, 46, 46,0.000000 }, - { 645, 645, 44, 0, 486, 486,0.000000 }, - { 645, 645, 43, 0, 473, 473,0.000000 }, - { 646, 646, 0, 0, 653, 653,0.000000 }, - { 647, 647, 0, 0, 2280, 2280,0.000000 }, - { 648, 648, 0, 0, 526, 526,0.000000 }, - { 649, 649, 0, 0, 40000, 40,0.000000 }, - { 650, 650, 0, 0, 40, 40,0.000000 }, - { 651, 651, 0, 0, 933, 933,0.000000 }, - { 652, 652, 0, 0, 40000, 300,0.000000 }, - { 653, 653, 0, 0, 280, 280,0.000000 }, - { 654, 654, 0, 0, 40000, 6,0.000000 }, - { 655, 655, 0, 0, 40000, 0,0.000000 }, - { 656, 656, 0, 0, 40000, 6,0.000000 }, - { 657, 657, 0, 0, 280, 280,0.000000 }, - { 658, 658, 0, 0, 513, 513,0.000000 }, - { 659, 659, 0, 0, 40000, 6,0.000000 }, - { 660, 660, 0, 0, 600, 600,0.000000 }, - { 661, 661, 0, 0, 646, 646,0.000000 }, - { 662, 662, 0, 0, 1166, 1166,0.000000 }, - { 663, 663, 0, 0, 40, 40,0.000000 }, - { 664, 664, 0, 0, 2073, 2073,0.000000 }, - { 665, 665, 0, 0, 40000, 106,0.000000 }, - { 666, 666, 0, 0, 40000, 146,0.000000 }, - { 667, 667, 0, 0, 40000, 126,0.000000 }, - { 668, 668, 0, 0, 280, 280,0.000000 }, - { 669, 669, 0, 0, 40000, 73,0.000000 }, - { 670, 670, 0, 0, 393, 393,0.000000 }, - { 671, 671, 0, 0, 760, 760,0.000000 }, - { 672, 672, 0, 0, 40000, 233,0.000000 }, - { 673, 673, 0, 0, 253, 253,0.000000 }, - { 674, 674, 0, 0, 186, 186,0.000000 }, - { 675, 675, 0, 0, 40000, 46,0.000000 }, - { 676, 676, 0, 0, 4773, 4773,0.000000 }, - { 677, 677, 0, 0, 2186, 2186,0.000000 }, - { 678, 678, 0, 0, 313, 313,0.000000 }, - { 679, 679, 0, 0, 1226, 1226,0.000000 }, - { 680, 680, 0, 0, 526, 13,0.000000 }, - { 681, 681, 0, 0, 40000, 0,0.000000 }, - { 682, 682, 0, 0, 40, 46,0.000000 }, - { 683, 683, 0, 0, 146, 146,0.000000 }, - { 684, 684, 0, 0, 2193, 2193,0.000000 }, - { 685, 685, 0, 0, 40000, 220,0.000000 }, - { 686, 686, 0, 0, 40000, 560,0.000000 }, - { 687, 687, 0, 0, 86, 86,0.000000 }, - { 688, 688, 0, 0, 40000, 1326,0.000000 }, - { 689, 689, 0, 0, 1166, 1166,0.000000 }, - { 690, 690, 0, 0, 593, 593,0.000000 }, - { 691, 691, 0, 0, 1580, 1580,0.000000 }, - { 692, 692, 0, 0, 513, 513,0.000000 }, - { 693, 693, 0, 0, 333, 333,0.000000 }, - { 694, 694, 0, 0, 1200, 1200,0.000000 }, - { 695, 695, 0, 0, 40000, 6,0.000000 }, - { 645, 645, 0, 0, 486, 486,0.000000 }, - { 696, 696, 0, 0, 40000, 6,0.000000 }, - { 697, 697, 0, 0, 333, 333,0.000000 }, - { 698, 698, 0, 0, 120, 120,0.000000 }, - { 699, 699, 0, 0, 40000, 6,0.000000 }, - { 700, 700, 0, 0, 13, 13,0.000000 }, - { 701, 701, 0, 0, 40000, 53,0.000000 }, - { 702, 702, 0, 0, 806, 806,0.000000 }, - { 703, 703, 0, 0, 40000, 6,0.000000 }, - { 704, 704, 0, 0, 40000, 6,0.000000 }, - { 705, 705, 0, 0, 40000, 0,0.000000 }, - { 706, 706, 0, 0, 40000, 6,0.000000 }, - { 707, 707, 0, 0, 40000, 166,0.000000 }, - { 708, 708, 0, 0, 40000, 26,0.000000 }, - { 709, 709, 0, 0, 40000, 146,0.000000 }, - { 710, 710, 0, 0, 1233, 6,0.000000 }, - { 711, 711, 0, 0, 146, 146,0.000000 }, - { 712, 712, 0, 0, 40000, 6,0.000000 }, - { 713, 713, 0, 0, 40000, 66,0.000000 }, - { 714, 714, 0, 0, 40000, 393,0.000000 }, - { 715, 715, 0, 0, 40000, 93,0.000000 }, - { 716, 716, 0, 0, 620, 620,0.000000 }, - { 717, 717, 0, 0, 40000, 6,0.000000 }, - { 718, 718, 0, 0, 493, 493,0.000000 }, - { 719, 719, 0, 0, 280, 280,0.000000 }, - { 720, 720, 0, 0, 760, 760,0.000000 }, - { 721, 721, 0, 0, 160, 160,0.000000 }, - { 722, 722, 0, 0, 40000, 106,0.000000 }, - { 723, 723, 0, 0, 166, 166,0.000000 }, - { 724, 724, 0, 0, 40000, 6,0.000000 }, - { 725, 725, 0, 0, 126, 126,0.000000 }, - { 726, 726, 0, 0, 593, 593,0.000000 }, - { 727, 727, 0, 0, 513, 513,0.000000 }, - { 728, 728, 0, 0, 246, 246,0.000000 }, - { 507, 507, 0, 0, 40, 40,0.000000 }, - { 512, 512, 0, 0, 93, 93,0.000000 }, - { 729, 729, 0, 0, 2406, 2406,0.000000 }, - { 730, 730, 0, 0, 2400, 2400,0.000000 }, - { 731, 731, 0, 0, 1153, 1153,0.000000 }, - { 732, 732, 0, 0, 40000, 1113,0.000000 }, - { 733, 733, 0, 0, 40000, 613,0.000000 }, - { 734, 734, 0, 0, 4453, 4453,0.000000 }, - { 735, 735, 0, 0, 160, 160,0.000000 }, - { 736, 736, 0, 0, 80, 80,0.000000 }, - { 737, 737, 0, 0, 1513, 13,0.000000 }, - { 738, 738, 38, 0, 33, 33,0.000000 }, - { 739, 739, 44, 0, 40, 40,0.000000 }, - { 500, 500, 58, 0, 13, 13,0.000000 }, - { 740, 740, 24, 0, 160, 160,0.000000 }, - { 741, 741, 60, 0, 133, 133,0.000000 }, - { 736, 736, 44, 0, 80, 80,0.000000 }, - { 742, 742, 25, 0, 146, 146,0.000000 }, - { 743, 743, 60, 0, 33, 33,0.000000 }, - { 742, 742, 30, 0, 146, 146,0.000000 }, - { 377, 377, 60, 0, 93, 93,0.000000 }, - { 742, 742, 33, 0, 173, 173,0.000000 }, - { 744, 744, 60, 0, 53, 53,0.000000 }, - { 742, 742, 35, 0, 186, 186,0.000000 }, - { 742, 742, 37, 0, 200, 200,0.000000 }, - { 745, 745, 0, 0, 313, 313,0.000000 }, - { 742, 742, 40, 0, 206, 206,0.000000 }, - { 746, 746,102, 0, 300, 300,0.000000 }, - { 747, 747, 80, 0, 433, 433,0.000000 }, - { 377, 377, 0, 0, 86, 86,0.000000 }, - { 748, 748, 56, 0, 13, 13,0.000000 }, - { 749, 749, 0, 0, 140, 140,0.000000 }, - { 746, 746,100, 0, 280, 280,0.000000 }, - { 750, 750, 40, 0, 200, 200,0.000000 }, - { 750, 750, 35, 0, 200, 200,0.000000 }, - { 751, 751, 29, 0, 53, 53,0.000000 }, - { 750, 750, 29, 0, 200, 200,0.000000 }, - { 750, 750, 22, 0, 206, 206,0.000000 }, - { 500, 500, 0, 0, 13, 13,0.000000 }, - { 752, 752, 0, 0, 46, 46,0.000000 }, - { 753, 753, 84, 0, 86, 86,0.000000 }, - { 754, 754, 84, 0, 506, 506,0.000000 }, - { 755, 755, 0, 0, 160, 160,0.000000 }, - { 755, 755, 71, 0, 133, 133,0.000000 }, - { 755, 755, 53, 0, 160, 160,0.000000 }, - { 755, 755, 48, 0, 160, 160,0.000000 }, - { 756, 756, 95, 0, 200, 200,0.000000 }, - { 757, 757, 95, 0, 613, 613,0.000000 }, - { 758, 758, 0, 0, 866, 866,0.000000 }, - { 759, 759, 0, 0, 933, 933,0.000000 }, - { 760, 760, 0, 0, 2393, 2393,0.000000 }, - { 761, 761, 0, 0, 760, 760,0.000000 }, - { 762, 762, 0, 0, 1740, 1740,0.000000 }, - { 763, 763, 0, 0, 1846, 1846,0.000000 }, - { 764, 764, 0, 0, 2106, 2106,0.000000 }, - { 765, 765, 0, 0, 1193, 1193,0.000000 }, - { 766, 766, 0, 0, 1613, 1613,0.000000 }, - { 767, 767, 0, 0, 673, 673,0.000000 }, - { 768, 768, 0, 0, 280, 280,0.000000 }, - { 769, 769, 0, 0, 1740, 1740,0.000000 }, - { 770, 770, 0, 0, 193, 193,0.000000 }, - { 771, 771, 0, 0, 140, 140,0.000000 }, - { 772, 772, 0, 0, 933, 933,0.000000 }, - { 773, 773, 0, 0, 333, 333,0.000000 }, - { 774, 774, 0, 0, 40000, 6,0.000000 }, - { 775, 775, 0, 0, 40000, 6,0.000000 }, - { 776, 776, 0, 0, 613, 13,0.000000 }, - { 777, 777, 0, 0, 40000, 80,0.000000 }, - { 778, 778, 0, 0, 40000, 26,0.000000 }, - { 779, 779, 0, 0, 40000, 20,0.000000 }, - { 780, 780, 0, 0, 40000, 20,0.000000 }, - { 781, 781, 0, 0, 40000, 66,0.000000 }, - { 782, 782, 0, 0, 940, 940,0.000000 }, - { 783, 783, 0, 0, 566, 566,0.000000 }, - { 784, 784, 0, 0, 1846, 1846,0.000000 }, - { 785, 785, 0, 0, 1120, 1120,0.000000 }, - { 786, 786, 0, 0, 300, 300,0.000000 }, - { 787, 787, 0, 0, 3000, 3000,0.000000 }, - { 788, 788, 0, 0, 3773, 3773,0.000000 }, - { 789, 789, 0, 0, 620, 620,0.000000 }, - { 790, 790, 0, 0, 846, 846,0.000000 }, - { 791, 791, 0, 0, 4846, 4846,0.000000 }, - { 792, 792, 0, 0, 1133, 1133,0.000000 }, - { 793, 793, 0, 0, 1446, 1446,0.000000 }, - { 794, 794, 0, 0, 566, 566,0.000000 }, - { 795, 795, 0, 0, 600, 600,0.000000 }, - { 796, 796, 0, 0, 1180, 1180,0.000000 }, - { 797, 797, 0, 0, 893, 893,0.000000 }, - { 798, 798, 0, 0, 40000, 20,0.000000 }, - { 799, 799, 0, 0, 40000, 20,0.000000 }, - { 800, 800, 0, 0, 166, 40,0.000000 }, - { 801, 801, 0, 0, 2286, 2286,0.000000 }, - { 802, 802, 0, 0, 40000, 86,0.000000 }, - { 803, 803, 0, 0, 120, 120,0.000000 }, - { 804, 804, 0, 0, 440, 440,0.000000 }, - { 805, 805, 0, 0, 286, 286,0.000000 }, - { 806, 806, 0, 0, 40000, 86,0.000000 }, - { 807, 807, 0, 0, 5473, 120,0.000000 }, - { 808, 808, 0, 0, 100, 13,0.000000 }, - { 809, 809, 0, 0, 40000, 53,0.000000 }, - { 810, 810, 0, 0, 1640, 6,0.000000 }, - { 811, 811, 0, 0, 40000, 53,0.000000 }, - { 812, 812, 0, 0, 1026, 13,0.000000 }, - { 813, 813, 0, 0, 186, 186,0.000000 }, - { 814, 814, 0, 0, 40, 40,0.000000 }, - { 815, 815, 0, 0, 40000, 20,0.000000 }, - { 816, 816, 0, 0, 40000, 20,0.000000 }, - { 817, 817, 0, 0, 873, 873,0.000000 }, - { 818, 818, 0, 0, 4440, 4440,0.000000 }, - { 819, 819, 0, 0, 273, 6,0.000000 }, - { 820, 820, 0, 0, 40000, 53,0.000000 }, - { 821, 821, 0, 0, 40000, 106,0.000000 }, - { 822, 822, 0, 0, 40000, 6,0.000000 }, - { 823, 823, 0, 0, 40000, 0,0.000000 }, - { 824, 824, 0, 0, 40000, 13,0.000000 }, - { 825, 825, 0, 0, 40000, 33,0.000000 }, - { 826, 826, 0, 0, 40000, 20,0.000000 }, - { 827, 827, 0, 0, 40000, 6,0.000000 }, - { 828, 828, 0, 0, 40000, 6,0.000000 }, - { 829, 829, 0, 0, 40000, 20,0.000000 }, - { 830, 830, 0, 0, 40000, 20,0.000000 }, - { 831, 831, 0, 0, 40000, 6,0.000000 }, - { 832, 832, 0, 0, 40000, 13,0.000000 }, - { 833, 833, 0, 0, 40000, 20,0.000000 }, - { 834, 834, 0, 0, 40000, 20,0.000000 }, - { 835, 835, 0, 0, 40000, 20,0.000000 }, - { 836, 836, 0, 0, 40000, 33,0.000000 }, - { 837, 837, 0, 0, 40000, 53,0.000000 }, - { 838, 838, 0, 0, 40000, 6,0.000000 }, - { 839, 839, 0, 0, 1153, 1153,0.000000 }, - { 840, 840, 0, 0, 40000, 20,0.000000 }, - { 841, 841, 0, 0, 20, 20,0.000000 }, - { 842, 842, 0, 0, 2040, 2040,0.000000 }, - { 843, 843, 0, 0, 40000, 6,0.000000 }, - { 844, 844, 0, 0, 40000, 13,0.000000 }, - { 845, 845, 0, 0, 1153, 1153,0.000000 }, - { 846, 846, 0, 0, 1526, 80,0.000000 }, - { 847, 847, 0, 0, 40000, 180,0.000000 }, - { 848, 848, 0, 0, 40000, 86,0.000000 }, - { 849, 849, 0, 0, 40000, 26,0.000000 }, - { 850, 850, 0, 0, 40000, 53,0.000000 }, - { 851, 851, 0, 0, 2886, 2886,0.000000 }, - { 852, 852, 0, 0, 40000, 73,0.000000 }, - { 853, 853, 0, 0, 40000, 126,0.000000 }, - { 854, 854, 0, 0, 1706, 1706,0.000000 }, - { 855, 855, 0, 0, 40000, 213,0.000000 }, - { 856, 856, 0, 0, 920, 920,0.000000 }, - { 857, 857, 0, 0, 993, 993,0.000000 }, - { 858, 858, 0, 0, 1613, 1613,0.000000 }, - { 859, 859, 0, 0, 1000, 106,0.000000 }, - { 860, 860, 0, 0, 40000, 20,0.000000 }, - { 861, 861, 0, 0, 40000, 213,0.000000 }, - { 862, 862, 0, 0, 766, 766,0.000000 }, - { 863, 863, 0, 0, 153, 153,0.000000 }, - { 864, 864, 0, 0, 626, 626,0.000000 }, - { 865, 865, 0, 0, 506, 506,0.000000 }, - { 866, 866, 0, 0, 300, 300,0.000000 }, - { 867, 867, 0, 0, 40000, 33,0.000000 }, - { 868, 868, 0, 0, 40000, 33,0.000000 }, - { 869, 869, 0, 0, 40000, 20,0.000000 }, - { 870, 870, 0, 0, 2106, 2106,0.000000 }, - { 871, 871, 0, 0, 93, 93,0.000000 }, - { 872, 872, 0, 0, 213, 213,0.000000 }, - { 361, 361, 0, 0, 80, 80,0.000000 }, - { 873, 873, 0, 0, 100, 100,0.000000 }, - { 874, 874, 0, 0, 80, 80,0.000000 }, - { 875, 875, 0, 0, 300, 300,0.000000 }, - { 876, 876, 0, 0, 3186, 3186,0.000000 }, - { 877, 877, 0, 0, 226, 226,0.000000 }, - { 878, 878, 0, 0, 53, 53,0.000000 }, - { 879, 879, 0, 0, 2833, 2833,0.000000 }, - { 880, 880, 0, 0, 113, 113,0.000000 }, - { 881, 881, 0, 0, 40000, 40,0.000000 }, - { 882, 882, 0, 0, 40000, 300,0.000000 }, - { 883, 883, 0, 0, 2793, 2793,0.000000 }, - { 884, 884, 36, 0, 73, 73,0.000000 }, - { 885, 885, 48, 0, 60, 60,0.000000 }, - { 885, 885, 36, 0, 73, 73,0.000000 }, - { 886, 886, 36, 0, 20, 20,0.000000 }, - { 887, 887, 32, 0, 46, 46,0.000000 }, - { 767, 767, 96, 0, 580, 580,0.000000 }, - { 888, 888, 30, 0, 53, 53,0.000000 }, - { 889, 889, 35, 0, 106, 106,0.000000 }, - { 890, 890, 60, 0, 86, 86,0.000000 }, - { 884, 884, 59, 0, 40, 40,0.000000 }, - { 890, 890, 44, 0, 80, 80,0.000000 }, - { 891, 891, 41, 0, 166, 166,0.000000 }, - { 892, 892, 47, 0, 40, 40,0.000000 }, - { 891, 891, 44, 0, 140, 140,0.000000 }, - { 891, 891, 48, 0, 153, 153,0.000000 }, - { 893, 893, 62, 0, 606, 606,0.000000 }, - { 891, 891, 51, 0, 160, 160,0.000000 }, - { 891, 891, 54, 0, 160, 160,0.000000 }, - { 894, 894, 40, 0, 386, 386,0.000000 }, - { 891, 891, 57, 0, 113, 113,0.000000 }, - { 895, 895, 97, 0, 73, 73,0.000000 }, - { 896, 896, 50, 0, 86, 86,0.000000 }, - { 376, 376, 60, 0, 153, 153,0.000000 }, - { 897, 897, 53, 0, 33, 33,0.000000 }, - { 898, 898, 46, 0, 53, 53,0.000000 }, - { 897, 897, 57, 0, 33, 33,0.000000 }, - { 899, 899, 42, 0, 193, 193,0.000000 }, - { 899, 899, 37, 0, 200, 200,0.000000 }, - { 900, 900, 41, 0, 200, 200,0.000000 }, - { 900, 900, 37, 0, 193, 193,0.000000 }, - { 871, 871, 77, 0, 46, 46,0.000000 }, - { 871, 871, 72, 0, 40, 40,0.000000 }, - { 388, 388, 70, 0, 46, 46,0.000000 }, - { 901, 901, 39, 0, 173, 173,0.000000 }, - { 902, 902, 36, 0, 1006, 1006,0.000000 }, - { 903, 903, 46, 0, 33, 33,0.000000 }, - { 904, 904, 48, 0, 680, 680,0.000000 }, - { 905, 905, 85, 0, 33, 33,0.000000 }, - { 361, 361, 66, 0, 60, 60,0.000000 }, - { 906, 906, 41, 0, 106, 106,0.000000 }, - { 907, 907, 41, 0, 93, 93,0.000000 }, - { 908, 908, 81, 0, 33, 33,0.000000 }, - { 400, 400, 10, 0, 313, 313,0.000000 }, - { 886, 886, 60, 0, 13, 13,0.000000 }, - { 873, 873, 53, 0, 166, 166,0.000000 }, - { 909, 909, 0, 0, 566, 566,0.000000 }, - { 910, 910, 0, 0, 1313, 1313,0.000000 }, - { 911, 911, 0, 0, 760, 760,0.000000 }, - { 912, 912, 0, 0, 760, 760,0.000000 }, - { 913, 913, 0, 0, 1740, 1740,0.000000 }, - { 914, 914, 0, 0, 1900, 1900,0.000000 }, - { 915, 915, 0, 0, 1173, 1173,0.000000 }, - { 916, 916, 0, 0, 1233, 1233,0.000000 }, - { 917, 917, 0, 0, 493, 493,0.000000 }, - { 362, 362, 0, 0, 246, 246,0.000000 }, - { 918, 918, 0, 0, 226, 226,0.000000 }, - { 919, 919, 0, 0, 1740, 1740,0.000000 }, - { 920, 920, 0, 0, 246, 246,0.000000 }, - { 921, 921, 0, 0, 120, 120,0.000000 }, - { 922, 922, 0, 0, 606, 606,0.000000 }, - { 923, 923, 0, 0, 333, 333,0.000000 }, - { 924, 924, 0, 0, 40000, 6,0.000000 }, - { 925, 925, 0, 0, 40000, 6,0.000000 }, - { 926, 926, 0, 0, 13, 13,0.000000 }, - { 927, 927, 0, 0, 40000, 66,0.000000 }, - { 928, 928, 0, 0, 40000, 26,0.000000 }, - { 929, 929, 0, 0, 40000, 20,0.000000 }, - { 930, 930, 0, 0, 40000, 20,0.000000 }, - { 931, 931, 0, 0, 40000, 33,0.000000 }, - { 932, 932, 0, 0, 866, 866,0.000000 }, - { 933, 933, 0, 0, 566, 566,0.000000 }, - { 934, 934, 0, 0, 1900, 1900,0.000000 }, - { 935, 935, 0, 0, 1146, 1146,0.000000 }, - { 936, 936, 0, 0, 606, 606,0.000000 }, - { 937, 937, 0, 0, 4673, 4673,0.000000 }, - { 938, 938, 0, 0, 3126, 3126,0.000000 }, - { 939, 939, 0, 0, 2406, 2406,0.000000 }, - { 940, 940, 0, 0, 440, 440,0.000000 }, - { 941, 941, 0, 0, 3200, 3200,0.000000 }, - { 942, 942, 0, 0, 1000, 1000,0.000000 }, - { 943, 943, 0, 0, 593, 593,0.000000 }, - { 944, 944, 0, 0, 546, 546,0.000000 }, - { 945, 945, 0, 0, 620, 620,0.000000 }, - { 946, 946, 0, 0, 1206, 1206,0.000000 }, - { 947, 947, 0, 0, 680, 680,0.000000 }, - { 948, 948, 0, 0, 40000, 20,0.000000 }, - { 949, 949, 0, 0, 40000, 20,0.000000 }, - { 950, 950, 0, 0, 4793, 33,0.000000 }, - { 951, 951, 0, 0, 1773, 1773,0.000000 }, - { 952, 952, 0, 0, 40000, 86,0.000000 }, - { 953, 953, 0, 0, 173, 173,0.000000 }, - { 954, 954, 0, 0, 406, 406,0.000000 }, - { 955, 955, 0, 0, 280, 280,0.000000 }, - { 956, 956, 0, 0, 5453, 33,0.000000 }, - { 957, 957, 0, 0, 2466, 100,0.000000 }, - { 958, 958, 0, 0, 973, 973,0.000000 }, - { 959, 959, 0, 0, 40000, 53,0.000000 }, - { 960, 960, 0, 0, 40000, 33,0.000000 }, - { 961, 961, 0, 0, 1026, 13,0.000000 }, - { 962, 962, 0, 0, 166, 166,0.000000 }, - { 963, 963, 0, 0, 806, 806,0.000000 }, - { 964, 964, 0, 0, 40000, 20,0.000000 }, - { 965, 965, 0, 0, 60, 20,0.000000 }, - { 966, 966, 0, 0, 1020, 1020,0.000000 }, - { 967, 967, 0, 0, 3426, 3426,0.000000 }, - { 968, 968, 0, 0, 40000, 20,0.000000 }, - { 969, 969, 0, 0, 40000, 20,0.000000 }, - { 970, 970, 0, 0, 40000, 106,0.000000 }, - { 971, 971, 0, 0, 40000, 6,0.000000 }, - { 972, 972, 0, 0, 40000, 0,0.000000 }, - { 973, 973, 0, 0, 2280, 2280,0.000000 }, - { 974, 974, 0, 0, 40000, 20,0.000000 }, - { 975, 975, 0, 0, 40000, 6,0.000000 }, - { 976, 976, 0, 0, 40000, 6,0.000000 }, - { 977, 977, 0, 0, 40000, 0,0.000000 }, - { 978, 978, 0, 0, 40000, 6,0.000000 }, - { 979, 979, 0, 0, 40000, 33,0.000000 }, - { 980, 980, 0, 0, 40000, 0,0.000000 }, - { 981, 981, 0, 0, 40000, 13,0.000000 }, - { 982, 982, 0, 0, 40000, 20,0.000000 }, - { 983, 983, 0, 0, 40000, 33,0.000000 }, - { 984, 984, 0, 0, 40000, 20,0.000000 }, - { 985, 985, 0, 0, 40000, 33,0.000000 }, - { 986, 986, 0, 0, 40000, 20,0.000000 }, - { 987, 987, 0, 0, 40000, 6,0.000000 }, - { 988, 988, 0, 0, 1133, 1133,0.000000 }, - { 989, 989, 0, 0, 40000, 20,0.000000 }, - { 990, 990, 0, 0, 1340, 1340,0.000000 }, - { 991, 991, 0, 0, 3533, 3533,0.000000 }, - { 992, 992, 0, 0, 40000, 6,0.000000 }, - { 993, 993, 0, 0, 40000, 26,0.000000 }, - { 994, 994, 0, 0, 4140, 4140,0.000000 }, - { 995, 995, 0, 0, 1206, 1206,0.000000 }, - { 996, 996, 0, 0, 40000, 173,0.000000 }, - { 997, 997, 0, 0, 380, 80,0.000000 }, - { 998, 998, 0, 0, 40000, 26,0.000000 }, - { 999, 999, 0, 0, 40000, 20,0.000000 }, - {1000,1000, 0, 0, 2893, 2893,0.000000 }, - {1001,1001, 0, 0, 40000, 73,0.000000 }, - {1002,1002, 0, 0, 40000, 126,0.000000 }, - {1003,1003, 0, 0, 4373, 4373,0.000000 }, - {1004,1004, 0, 0, 40000, 240,0.000000 }, - {1005,1005, 0, 0, 993, 993,0.000000 }, - {1006,1006, 0, 0, 760, 760,0.000000 }, - {1007,1007, 0, 0, 1380, 1380,0.000000 }, - {1008,1008, 0, 0, 726, 53,0.000000 }, - {1009,1009, 0, 0, 40000, 33,0.000000 }, - {1010,1010, 0, 0, 40000, 213,0.000000 }, - {1011,1011, 0, 0, 1046, 1046,0.000000 }, - {1012,1012, 0, 0, 273, 273,0.000000 }, - {1013,1013, 0, 0, 626, 626,0.000000 }, - {1014,1014, 0, 0, 1166, 1166,0.000000 }, - {1015,1015, 0, 0, 153, 153,0.000000 }, - {1016,1016, 0, 0, 40000, 6,0.000000 }, - {1017,1017, 0, 0, 40000, 33,0.000000 }, - {1018,1018, 0, 0, 40000, 20,0.000000 }, - {1019,1019, 0, 0, 2106, 2106,0.000000 }, - { 444, 444, 0, 0, 86, 86,0.000000 }, - {1020,1020, 0, 0, 180, 180,0.000000 }, - { 449, 449, 0, 0, 80, 80,0.000000 }, - { 453, 453, 0, 0, 20, 20,0.000000 }, - {1021,1021, 0, 0, 20, 20,0.000000 }, - {1022,1022, 0, 0, 246, 246,0.000000 }, - {1023,1023, 0, 0, 3186, 3186,0.000000 }, - {1024,1024, 0, 0, 226, 226,0.000000 }, - {1025,1025, 0, 0, 186, 186,0.000000 }, - {1026,1026, 0, 0, 2833, 2833,0.000000 }, - {1027,1027, 0, 0, 2460, 2460,0.000000 }, - {1028,1028, 0, 0, 40000, 40,0.000000 }, - {1029,1029, 0, 0, 40000, 286,0.000000 }, - {1030,1030, 0, 0, 40000, 146,0.000000 }, - {1031,1031, 0, 0, 586, 586,0.000000 }, - {1032,1032, 32, 0, 46, 46,0.000000 }, - {1033,1033, 30, 0, 26, 26,0.000000 }, - {1034,1034, 96, 0, 40, 40,0.000000 }, - {1035,1035, 60, 0, 186, 186,0.000000 }, - {1036,1036, 0, 0, 1100, 1100,0.000000 }, - {1037,1037, 0, 0, 40000, 33,0.000000 }, - {1038,1038, 0, 0, 1740, 1740,0.000000 }, - {1039,1039, 0, 0, 1793, 1793,0.000000 }, - {1040,1040, 0, 0, 160, 160,0.000000 }, - {1041,1041, 0, 0, 1206, 1206,0.000000 }, - {1042,1042, 0, 0, 353, 353,0.000000 }, - {1043,1043, 0, 0, 40000, 6,0.000000 }, - {1044,1044, 0, 0, 40000, 0,0.000000 }, - {1045,1045, 0, 0, 40000, 20,0.000000 }, - {1046,1046, 0, 0, 1186, 1186,0.000000 }, - {1047,1047, 0, 0, 1093, 1093,0.000000 }, - {1048,1048, 0, 0, 620, 620,0.000000 }, - {1049,1049, 0, 0, 4440, 4440,0.000000 }, - {1050,1050, 0, 0, 4506, 4506,0.000000 }, - {1051,1051, 0, 0, 4673, 4673,0.000000 }, - {1052,1052, 0, 0, 2386, 2386,0.000000 }, - {1053,1053, 0, 0, 40000, 146,0.000000 }, - {1054,1054, 0, 0, 1180, 1180,0.000000 }, - {1055,1055, 0, 0, 320, 320,0.000000 }, - {1056,1056, 0, 0, 633, 633,0.000000 }, - {1057,1057, 0, 0, 80, 80,0.000000 }, - {1058,1058, 0, 0, 1180, 1180,0.000000 }, - {1059,1059, 0, 0, 6120, 100,0.000000 }, - {1060,1060, 0, 0, 86, 86,0.000000 }, - {1061,1061, 0, 0, 206, 206,0.000000 }, - {1062,1062, 0, 0, 40000, 86,0.000000 }, - {1063,1063, 0, 0, 40000, 266,0.000000 }, - {1064,1064, 0, 0, 806, 806,0.000000 }, - {1065,1065, 0, 0, 40000, 20,0.000000 }, - {1066,1066, 0, 0, 40000, 53,0.000000 }, - {1067,1067, 0, 0, 40000, 53,0.000000 }, - {1068,1068, 0, 0, 40000, 26,0.000000 }, - {1069,1069, 0, 0, 40000, 20,0.000000 }, - {1070,1070, 0, 0, 40000, 20,0.000000 }, - {1071,1071, 0, 0, 40000, 6,0.000000 }, - {1072,1072, 0, 0, 40000, 26,0.000000 }, - {1073,1073, 0, 0, 40000, 13,0.000000 }, - {1074,1074, 0, 0, 40000, 60,0.000000 }, - {1075,1075, 0, 0, 213, 213,0.000000 }, - {1076,1076, 0, 0, 40000, 73,0.000000 }, - {1077,1077, 0, 0, 4513, 4513,0.000000 }, - {1078,1078, 0, 0, 313, 313,0.000000 }, - {1079,1079, 0, 0, 4273, 4273,0.000000 }, - {1080,1080, 0, 0, 40000, 26,0.000000 }, - {1081,1081, 0, 0, 3153, 3153,0.000000 }, - {1082,1082, 0, 0, 40000, 180,0.000000 }, - {1083,1083, 0, 0, 40000, 213,0.000000 }, - {1084,1084, 0, 0, 1740, 13,0.000000 }, - {1085,1085, 0, 0, 2853, 2853,0.000000 }, - {1086,1086, 0, 0, 40000, 213,0.000000 }, - {1087,1087, 0, 0, 3946, 3946,0.000000 }, - {1088,1088, 0, 0, 2253, 2253,0.000000 }, - {1089,1089, 0, 0, 40000, 260,0.000000 }, - {1090,1090, 0, 0, 166, 166,0.000000 }, - {1091,1091, 0, 0, 40000, 493,0.000000 }, - {1092,1092, 0, 0, 2126, 2126,0.000000 }, - {1093,1093, 0, 0, 40000, 480,0.000000 }, - {1094,1094, 0, 0, 40000, 213,0.000000 }, - {1095,1095, 0, 0, 146, 146,0.000000 }, - {1096,1096, 0, 0, 333, 333,0.000000 }, - {1097,1097, 0, 0, 466, 466,0.000000 }, - {1098,1098, 0, 0, 40000, 40,0.000000 }, - {1099,1099, 0, 0, 4926, 4926,0.000000 }, - {1100,1100, 0, 0, 5113, 5113,0.000000 }, - {1101,1101, 0, 0, 3060, 13,0.000000 }, - {1102,1102, 0, 0, 420, 420,0.000000 }, - {1103,1103, 0, 0, 300, 300,0.000000 }, - {1104,1104, 0, 0, 4426, 4426,0.000000 }, - {1105,1105, 0, 0, 5513, 5513,0.000000 }, - {1106,1106, 0, 0, 40000, 233,0.000000 }, - { 430, 430, 0, 0, 300, 300,0.000000 }, - {1107,1107, 35, 0, 73, 73,0.000000 }, - {1090,1090, 77, 0, 80, 80,0.000000 }, - {1090,1090, 72, 0, 80, 80,0.000000 }, - {1108,1108, 0, 0, 60, 60,0.000000 }, - {1109,1109, 0, 0, 1453, 1453,0.000000 }, - {1110,1111, 0, 1, 506, 506,0.000000 }, - {1112,1113, 0, 1, 1253, 1253,0.031250 }, - {1114,1114, 0, 0, 866, 866,0.000000 }, - {1115,1116, 0, 1, 1473, 1473,0.000000 }, - {1117,1117, 0, 0, 1600, 1600,0.000000 }, - {1118,1118, 0, 0, 680, 680,0.000000 }, - {1119,1119, 0, 0, 1133, 1133,0.000000 }, - {1120,1120, 0, 0, 1013, 1013,0.000000 }, - {1121,1121, 0, 0, 860, 860,0.000000 }, - {1122,1122, 0, 0, 1473, 1473,0.000000 }, - {1123,1123, 0, 0, 280, 280,0.000000 }, - {1124,1124, 0, 0, 53, 53,0.000000 }, - {1125,1125, 0, 0, 1260, 1260,0.000000 }, - {1126,1126, 0, 0, 906, 906,0.000000 }, - {1127,1127, 0, 0, 40000, 66,0.000000 }, - {1128,1128, 0, 0, 260, 13,0.000000 }, - {1129,1130, 0, 1, 13973, 13,0.156250 }, - {1131,1131, 0, 0, 40000, 173,0.000000 }, - {1132,1132, 0, 0, 40000, 53,0.000000 }, - {1133,1134, 0, 1, 40000, 20,-0.046875 }, - {1135,1135, 0, 0, 40000, 26,0.000000 }, - {1136,1137, 0, 1, 40000, 113,0.000025 }, - {1138,1138, 0, 0, 3366, 3366,0.000000 }, - {1139,1139, 0, 0, 400, 400,0.000000 }, - {1140,1140, 0, 0, 473, 473,0.000000 }, - {1141,1141, 0, 0, 840, 840,0.000000 }, - {1142,1142, 0, 0, 800, 800,0.000000 }, - {1143,1143, 0, 0, 2173, 0,0.000000 }, - {1144,1144, 0, 0, 40000, 0,0.000000 }, - {1145,1145, 0, 0, 1433, 1433,0.000000 }, - {1146,1146, 0, 0, 386, 386,0.000000 }, - {1147,1147, 0, 0, 1253, 1253,0.000000 }, - {1148,1148, 0, 0, 1606, 1606,0.000000 }, - {1149,1150, 0, 1, 1553, 1553,-0.031250 }, - {1151,1151, 0, 0, 40000, 6,0.000000 }, - {1152,1152, 0, 0, 1560, 1560,0.000000 }, - {1153,1153, 0, 0, 386, 386,0.000000 }, - {1154,1154, 0, 1, 40000, 20,-0.156250 }, - {1155,1155, 0, 0, 3886, 6,0.000000 }, - {1156,1156, 0, 0, 40000, 66,0.000000 }, - {1157,1157, 0, 0, 40000, 60,0.000000 }, - {1158,1158, 0, 0, 40000, 266,0.000000 }, - {1159,1160, 0, 1, 40000, 273,0.171875 }, - {1161,1161, 0, 0, 173, 173,0.000000 }, - {1162,1162, 0, 0, 993, 993,0.000000 }, - {1163,1163, 0, 0, 726, 726,0.000000 }, - {1164,1165, 0, 1, 40000, 206,-0.125000 }, - {1166,1167, 0, 1, 40000, 266,0.078125 }, - {1168,1168, 0, 1, 40000, 1073,-0.078125 }, - {1169,1170, 0, 1, 40000, 253,0.062500 }, - {1171,1172, 0, 1, 40000, 533,0.156250 }, - {1173,1173, 0, 0, 1813, 1813,0.000000 }, - {1174,1174, 0, 0, 40000, 200,0.000000 }, - {1175,1176, 0, 1, 360, 360,0.000000 }, - {1177,1177, 0, 0, 40000, 6,0.000000 }, - {1178,1178, 0, 0, 806, 6,0.000000 }, - {1179,1179, 0, 0, 1600, 1600,0.000000 }, - {1180,1180, 0, 0, 60, 60,0.000000 }, - {1181,1182, 0, 1, 3153, 3153,0.000025 }, - {1183,1184, 0, 1, 826, 6,0.046875 }, - {1185,1186, 0, 1, 3106, 3106,0.093750 }, - {1187,1188, 0, 1, 1020, 1020,0.093750 }, - {1189,1189, 0, 0, 40000, 33,0.000000 }, - {1190,1190, 0, 0, 40000, 20,0.000000 }, - {1191,1191, 0, 0, 40000, 0,0.000000 }, - {1192,1192, 0, 0, 266, 6,0.000000 }, - {1193,1193, 0, 0, 40000, 33,0.000000 }, - {1194,1194, 0, 0, 40000, 26,0.000000 }, - {1195,1195, 0, 0, 40000, 0,0.000000 }, - {1196,1196, 0, 0, 40000, 13,0.000000 }, - {1197,1197, 0, 0, 40000, 0,0.000000 }, - {1198,1198, 0, 0, 40000, 6,0.000000 }, - {1199,1199, 0, 0, 40000, 53,0.000000 }, - {1200,1200, 0, 0, 40000, 20,0.000000 }, - {1201,1201, 0, 0, 40000, 20,0.000000 }, - {1202,1202, 0, 0, 140, 140,0.000000 }, - {1203,1203, 0, 0, 40000, 93,0.000000 }, - {1204,1204, 0, 0, 40000, 6,0.000000 }, - {1205,1206, 0, 1, 40000, 86,0.031250 }, - {1207,1208, 0, 1, 40000, 100,-0.000025 }, - {1209,1209, 0, 0, 40000, 53,0.000000 }, - {1210,1211, 0, 1, 40000, 0,0.031250 }, - {1212,1212, 0, 0, 40000, 0,0.000000 }, - {1213,1214, 0, 1, 40000, 320,-0.093750 }, - {1215,1216, 0, 1, 1660, 80,-0.046875 }, - {1217,1217, 0, 0, 40000, 66,0.000000 }, - {1218,1219, 0, 1, 40000, 233,0.031250 }, - {1220,1220, 0, 1, 1960, 1960,0.031250 }, - {1221,1222, 0, 1, 17500, 46,0.171875 }, - {1223,1223, 0, 0, 2273, 2273,0.000000 }, - {1224,1224, 0, 0, 1933, 1933,0.000000 }, - {1225,1150, 0, 1, 3126, 13,-0.031250 }, - {1226,1226, 0, 0, 40000, 640,0.000000 }, - {1227,1227, 0, 0, 1080, 1080,0.000000 }, - {1228,1229, 0, 1, 40000, 33,0.125000 }, - {1230,1230, 0, 0, 1046, 1046,0.000000 }, - {1231,1232, 0, 1, 1553, 1553,-0.031250 }, - {1233,1234, 0, 1, 2066, 2066,-0.187500 }, - {1235,1235, 0, 0, 40000, 466,0.000000 }, - {1236,1236, 0, 0, 400, 400,0.000000 }, - {1237,1237, 0, 0, 2706, 2706,0.000000 }, - {1238,1238, 0, 0, 1220, 1220,0.000000 }, - {1239,1239, 0, 0, 446, 446,0.000000 }, - {1240,1241, 0, 1, 360, 360,0.000000 }, - {1242,1242, 0, 0, 4806, 4806,0.000000 }, - {1243,1243, 0, 0, 80, 80,0.000000 }, - {1244,1244, 0, 0, 40000, 80,0.000000 }, - {1245,1245, 0, 0, 40000, 86,0.000000 }, - {1246,1246, 0, 0, 40000, 40,0.000000 }, - {1247,1247, 0, 0, 1920, 1920,0.000000 }, - {1248,1248, 0, 0, 66, 66,0.000000 }, - {1249,1249, 0, 0, 40000, 233,0.000000 }, - {1250,1250, 0, 0, 113, 113,0.000000 }, - {1251,1251, 0, 0, 46, 46,0.000000 }, - {1252,1252, 0, 0, 140, 140,0.000000 }, - {1253,1253, 0, 0, 886, 886,0.000000 }, - {1254,1254, 0, 0, 1080, 1080,0.000000 }, - {1255,1255, 0, 0, 206, 206,0.000000 }, - {1256,1256, 0, 0, 280, 280,0.000000 }, - {1257,1257, 0, 0, 2873, 2873,0.000000 }, - {1258,1258, 0, 0, 313, 313,0.000000 }, - {1259,1259, 0, 0, 40000, 73,0.000000 }, - {1260,1260, 29, 0, 1320, 1320,0.000000 }, - {1261,1261, 65, 0, 40000, 1746,0.000000 }, - {1262,1262, 0, 0, 153, 153,0.000000 }, - {1263,1263, 25, 0, 33, 33,0.000000 }, - {1264,1264, 83, 0, 53, 53,0.000000 }, - {1265,1265, 32, 0, 40, 40,0.000000 }, - {1266,1266, 60, 0, 46, 46,0.000000 }, - {1267,1267, 36, 0, 46, 46,0.000000 }, - {1268,1268, 27, 0, 13, 13,0.000000 }, - {1269,1269, 31, 0, 266, 266,0.000000 }, - {1270,1270, 21, 0, 246, 246,0.000000 }, - {1270,1270, 26, 0, 253, 253,0.000000 }, - {1270,1270, 28, 0, 260, 260,0.000000 }, - {1271,1271, 60, 0, 280, 280,0.000000 }, - {1270,1270, 32, 0, 206, 206,0.000000 }, - {1272,1272, 60, 0, 260, 260,0.000000 }, - {1273,1273, 96, 0, 140, 140,0.000000 }, - {1274,1274, 72, 0, 133, 133,0.000000 }, - {1275,1275, 79, 0, 46, 46,0.000000 }, - {1276,1276, 69, 0, 126, 126,0.000000 }, - {1277,1277, 71, 0, 146, 146,0.000000 }, - {1278,1278, 22, 0, 566, 566,0.000000 }, - {1279,1279, 55, 0, 66, 66,0.000000 }, - {1279,1279, 48, 0, 80, 80,0.000000 }, - {1280,1280, 0, 0, 6, 6,0.000000 }, - {1281,1281, 49, 0, 6, 6,0.000000 }, - {1282,1282, 73, 0, 60, 60,0.000000 }, - {1282,1282, 68, 0, 60, 60,0.000000 }, - {1282,1282, 61, 0, 80, 80,0.000000 }, - {1283,1283, 0, 0, 6, 6,0.000000 }, - {1284,1284, 0, 0, 40000, 46,0.000000 }, - {1285,1285, 0, 0, 40000, 20,0.000000 }, - {1286,1286, 0, 0, 2380, 2380,0.000000 }, - {1287,1287, 0, 0, 700, 700,0.000000 }, - {1288,1289, 0, 1, 653, 6,0.000000 }, - {1290,1290, 0, 0, 80, 80,0.000000 }, - {1291,1292, 36, 1, 46, 46,0.000000 }, - {1293,1293, 69, 0, 126, 126,0.000000 }, - {1294,1294, 0, 0, 120, 120,0.000000 }, - {1295,1295, 0, 0, 40000, 0,0.000000 }, - {1296,1296, 0, 0, 1173, 1173,0.000000 }, - {1297,1297, 22, 0, 566, 566,0.000000 }, - {1298,1298, 0, 0, 40000, 0,0.000000 }, - {1299,1299, 0, 0, 993, 993,0.000000 }, - {1300,1300, 0, 0, 1900, 1900,0.000000 }, - {1301,1301, 0, 0, 1046, 1046,0.000000 }, - {1302,1302, 0, 0, 293, 293,0.000000 }, - {1303,1303, 0, 0, 40000, 33,0.000000 }, - {1304,1304, 0, 0, 40000, 6,0.000000 }, - {1305,1305, 0, 0, 40000, 20,0.000000 }, - {1306,1306, 0, 0, 40000, 193,0.000000 }, - {1307,1307, 0, 0, 40000, 153,0.000000 }, - {1308,1308, 0, 0, 40000, 6,0.000000 }, - {1309,1309, 0, 0, 40000, 46,0.000000 }, - {1310,1310, 0, 0, 40000, 73,0.000000 }, - {1311,1311, 0, 0, 920, 920,0.000000 }, - {1312,1312, 0, 0, 4580, 4580,0.000000 }, - {1313,1313, 0, 0, 1026, 1026,0.000000 }, - {1314,1314, 0, 0, 40000, 6,0.000000 }, - {1315,1315, 0, 0, 3746, 13,0.000000 }, - {1316,1316, 0, 0, 40000, 233,0.000000 }, - {1317,1317, 0, 0, 40000, 153,0.000000 }, - {1318,1318, 0, 0, 40000, 140,0.000000 }, - {1319,1319, 0, 0, 2620, 2620,0.000000 }, - {1320,1320, 0, 0, 40000, 140,0.000000 }, - {1321,1321, 0, 0, 233, 233,0.000000 }, - {1322,1322, 0, 0, 40000, 6,0.000000 }, - {1323,1323, 0, 0, 40000, 0,0.000000 }, - {1324,1324, 0, 0, 40000, 26,0.000000 }, - {1325,1325, 0, 0, 40000, 6,0.000000 }, - { 260, 260, 0, 0, 40000, 20,0.000000 }, - {1326,1326, 0, 0, 40000, 20,0.000000 }, - {1327,1327, 0, 0, 40000, 0,0.000000 }, - {1328,1328, 0, 0, 40000, 13,0.000000 }, - {1329,1329, 0, 0, 40000, 73,0.000000 }, - {1330,1330, 0, 0, 40000, 53,0.000000 }, - {1331,1331, 0, 0, 40000, 66,0.000000 }, - {1332,1332, 0, 0, 40000, 66,0.000000 }, - {1333,1333, 0, 0, 40000, 6,0.000000 }, - {1334,1334, 0, 0, 40000, 73,0.000000 }, - {1335,1335, 0, 0, 40000, 133,0.000000 }, - {1336,1336, 0, 0, 40000, 233,0.000000 }, - {1337,1337, 0, 0, 40000, 406,0.000000 }, - {1338,1338, 0, 0, 1766, 93,0.000000 }, - {1339,1339, 0, 0, 40000, 533,0.000000 }, - {1340,1340, 0, 0, 40000, 106,0.000000 }, - {1341,1341, 0, 0, 593, 13,0.000000 }, - {1342,1342, 0, 0, 940, 940,0.000000 }, - {1343,1343, 0, 0, 40000, 53,0.000000 }, - {1344,1344, 0, 0, 2006, 2006,0.000000 }, - {1345,1345, 0, 0, 40000, 933,0.000000 }, - {1346,1346, 0, 0, 973, 973,0.000000 }, - { 378, 378, 84, 0, 440, 440,0.000000 }, - {1347,1347, 24, 0, 46, 46,0.000000 }, - {1348,1348, 44, 0, 80, 80,0.000000 }, - {1349,1349, 40, 0, 306, 306,0.000000 }, - {1350,1350, 60, 0, 340, 340,0.000000 }, - {1351,1351, 0, 0, 866, 866,0.000000 }, - {1352,1352, 0, 0, 993, 993,0.000000 }, - {1353,1353, 0, 0, 633, 633,0.000000 }, - {1354,1354, 0, 0, 40000, 40,0.000000 }, - {1355,1355, 0, 0, 973, 973,0.000000 }, - {1356,1356, 0, 0, 40000, 126,0.000000 }, - {1357,1357, 0, 0, 166, 166,0.000000 }, - {1358,1358, 0, 0, 640, 640,0.000000 }, - {1359,1359, 0, 0, 100, 100,0.000000 }, - {1360,1360, 0, 0, 40000, 113,0.000000 }, - {1361,1361, 0, 0, 40000, 240,0.000000 }, - {1362,1362, 0, 0, 3793, 80,0.000000 }, - {1363,1363, 0, 0, 40000, 240,0.000000 }, - {1364,1364, 0, 0, 126, 126,0.000000 }, - {1365,1365, 0, 0, 40000, 20,0.000000 }, - {1366,1366, 0, 0, 40000, 26,0.000000 }, - {1367,1367, 0, 0, 2233, 6,0.000000 }, - {1368,1368, 0, 0, 40000, 53,0.000000 }, - {1369,1369, 0, 0, 40000, 33,0.000000 }, - {1370,1370, 0, 0, 40000, 13,0.000000 }, - {1371,1371, 0, 0, 40000, 13,0.000000 }, - {1372,1372, 0, 0, 40000, 26,0.000000 }, - {1373,1373, 0, 0, 40000, 6,0.000000 }, - {1374,1374, 0, 0, 40000, 13,0.000000 }, - {1375,1375, 0, 0, 4473, 13,0.000000 }, - {1376,1376, 0, 0, 146, 146,0.000000 }, - {1377,1377, 0, 0, 86, 86,0.000000 }, - {1378,1378, 35, 0, 73, 73,0.000000 }, - {1379,1379, 49, 0, 40, 40,0.000000 }, - {1377,1377, 48, 0, 80, 80,0.000000 }, - {1380,1380, 58, 0, 40, 40,0.000000 }, - {1377,1377, 60, 0, 86, 86,0.000000 }, - {1381,1381, 47, 0, 106, 106,0.000000 }, - {1382,1382, 60, 0, 20, 20,0.000000 }, - {1381,1381, 49, 0, 153, 153,0.000000 }, - {1383,1383, 72, 0, 80, 80,0.000000 }, - {1381,1381, 51, 0, 200, 200,0.000000 }, - {1384,1384, 84, 0, 273, 273,0.000000 }, - {1381,1381, 54, 0, 233, 233,0.000000 }, - {1381,1381, 57, 0, 260, 260,0.000000 }, - {1385,1385, 72, 0, 506, 506,0.000000 }, - {1381,1381, 60, 0, 306, 306,0.000000 }, - {1386,1386, 36, 0, 866, 866,0.000000 }, - {1387,1387, 93, 0, 66, 66,0.000000 }, - {1388,1388, 72, 0, 273, 273,0.000000 }, - {1389,1389, 84, 0, 426, 426,0.000000 }, - {1390,1390, 36, 0, 20, 20,0.000000 }, - {1391,1391, 64, 0, 86, 86,0.000000 }, - {1392,1392, 68, 0, 26, 26,0.000000 }, - {1393,1393, 0, 0, 1226, 1226,0.000000 }, - {1394,1394, 0, 0, 40000, 140,0.000000 }, - {1395,1395, 0, 0, 40000, 0,0.000000 }, - {1396,1396, 0, 0, 513, 513,0.000000 }, - {1397,1397, 0, 0, 40000, 126,0.000000 }, - {1398,1398, 0, 0, 320, 320,0.000000 }, - {1399,1399, 0, 0, 40000, 0,0.000000 }, - {1400,1400, 0, 0, 1766, 1766,0.000000 }, - {1401,1401, 0, 0, 2513, 2513,0.000000 }, - {1402,1402, 0, 0, 1300, 1300,0.000000 }, - {1403,1403, 0, 0, 46, 46,0.000000 }, - {1404,1404, 0, 0, 186, 6,0.000000 }, - {1405,1405, 0, 0, 40000, 6,0.000000 }, - {1406,1406, 0, 0, 40, 26,0.000000 }, - {1407,1407, 0, 0, 166, 166,0.000000 }, - {1408,1408, 0, 0, 2193, 2193,0.000000 }, - {1409,1409, 0, 0, 40000, 206,0.000000 }, - {1410,1410, 0, 0, 40000, 1460,0.000000 }, - {1411,1411, 0, 0, 166, 166,0.000000 }, - {1412,1412, 0, 0, 1380, 1380,0.000000 }, - {1413,1413, 0, 0, 533, 533,0.000000 }, - {1414,1414, 0, 0, 40000, 33,0.000000 }, - {1415,1415, 0, 0, 40000, 53,0.000000 }, - {1416,1416, 0, 0, 40000, 0,0.000000 }, - {1417,1417, 0, 0, 40000, 6,0.000000 }, - {1418,1418, 0, 0, 40000, 6,0.000000 }, - {1419,1419, 0, 0, 913, 913,0.000000 }, - {1420,1420, 0, 0, 1233, 6,0.000000 }, - {1421,1421, 0, 0, 126, 126,0.000000 }, - {1422,1422, 0, 0, 40000, 46,0.000000 }, - {1423,1423, 0, 0, 933, 933,0.000000 }, - {1424,1424, 0, 0, 1846, 1846,0.000000 }, - {1425,1425, 0, 0, 973, 973,0.000000 }, - {1426,1426, 0, 0, 160, 160,0.000000 }, - {1427,1427, 0, 0, 40000, 106,0.000000 }, - {1428,1428, 0, 0, 120, 120,0.000000 }, - {1429,1429, 0, 0, 40000, 6,0.000000 }, - {1430,1430, 0, 0, 93, 93,0.000000 }, - {1431,1431, 0, 0, 40, 40,0.000000 }, - {1432,1432, 0, 0, 2420, 2420,0.000000 }, - {1433,1433, 0, 0, 1153, 1153,0.000000 }, - {1434,1434, 0, 0, 2406, 2406,0.000000 }, - { 740, 740, 0, 0, 80, 80,0.000000 }, - {1435,1435, 0, 0, 40000, 3220,0.000000 }, - { 739, 739, 48, 0, 93, 93,0.000000 }, - { 500, 500, 55, 0, 13, 13,0.000000 }, - { 740, 740, 60, 0, 53, 53,0.000000 }, - { 500, 500, 41, 0, 13, 13,0.000000 }, - {1436,1436, 84, 0, 40, 40,0.000000 }, - {1437,1437, 84, 0, 73, 73,0.000000 }, - { 500, 500, 48, 0, 13, 13,0.000000 }, - {1438,1438, 15, 0, 86, 86,0.000000 }, - { 752, 752, 49, 0, 46, 46,0.000000 }, - {1438,1438, 16, 0, 93, 93,0.000000 }, - {1438,1438, 12, 0, 86, 86,0.000000 }, - { 740, 740, 55, 0, 53, 53,0.000000 }, - { 752, 752, 18, 0, 46, 46,0.000000 }, - { 752, 752, 15, 0, 46, 46,0.000000 }, - { 752, 752, 17, 0, 46, 46,0.000000 }, - {1439,1440, 0, 0, 1340, 1340,0.000000 }, - {1441,1442, 0, 0, 1113, 1113,0.000000 }, - {1443,1444, 0, 0, 2133, 2133,0.000000 }, - {1445,1446, 0, 0, 953, 953,0.000000 }, - {1447,1448, 0, 0, 100, 100,0.000000 }, - {1449,1450, 0, 0, 1313, 1313,0.000000 }, - { 181,1451, 0, 0, 473, 473,0.000000 }, - {1452,1453, 0, 0, 680, 680,0.000000 }, - {1454,1455, 0, 0, 260, 260,0.000000 }, - {1456,1457, 0, 0, 193, 193,0.000000 }, - {1458,1459, 0, 0, 1320, 1320,0.000000 }, - { 190,1460, 0, 0, 646, 6,0.000000 }, - { 192,1461, 0, 0, 40000, 6,0.000000 }, - {1462,1463, 0, 0, 40000, 113,0.000000 }, - {1464,1465, 0, 0, 40000, 133,0.000000 }, - {1466,1467, 0, 0, 40000, 6,0.000000 }, - {1468,1469, 0, 0, 40000, 0,0.000000 }, - { 35,1470, 0, 0, 1446, 1446,0.000000 }, - { 36,1471, 0, 0, 1606, 1606,0.000000 }, - {1472,1473, 0, 0, 1553, 1553,0.000000 }, - {1474,1475, 0, 0, 2133, 2133,0.000000 }, - { 39,1476, 0, 0, 40000, 26,0.000000 }, - {1477,1476, 0, 0, 40000, 46,0.000000 }, - {1478,1479, 0, 0, 40000, 240,0.000000 }, - { 50,1480, 0, 0, 40000, 153,0.000000 }, - {1481,1482, 0, 0, 40000, 46,0.000000 }, - {1483,1484, 0, 0, 2300, 2300,0.000000 }, - {1485,1486, 0, 0, 40000, 86,0.000000 }, - { 55,1487, 0, 0, 40000, 20,0.000000 }, - {1488,1489, 0, 0, 40000, 20,0.000000 }, - {1490,1491, 0, 0, 40000, 6,0.000000 }, - {1492,1493, 0, 0, 40000, 0,0.000000 }, - {1494,1495, 0, 0, 40000, 6,0.000000 }, - {1496,1497, 0, 0, 40000, 6,0.000000 }, - {1496,1498, 0, 0, 40000, 6,0.000000 }, - {1499,1500, 0, 0, 40000, 6,0.000000 }, - {1501,1502, 0, 0, 40000, 53,0.000000 }, - {1503,1504, 0, 0, 40000, 33,0.000000 }, - {1505,1506, 0, 0, 40000, 6,0.000000 }, - { 86,1507, 0, 0, 40000, 20,0.000000 }, - {1508,1509, 0, 0, 1766, 1766,0.000000 }, - {1510,1511, 0, 0, 2853, 13,0.000000 }, - {1512,1513, 0, 0, 593, 593,0.000000 }, - {1514,1515, 0, 0, 1126, 33,0.000000 }, - {1516,1517, 0, 0, 40000, 460,0.000000 }, - {1518,1519, 0, 0, 233, 233,0.000000 }, - {1520,1521, 0, 0, 40000, 213,0.000000 }, - {1522,1523, 0, 0, 1233, 1233,0.000000 }, - {1524,1525, 0, 0, 40000, 626,0.000000 }, - {1526,1527, 0, 0, 40000, 446,0.000000 }, - {1528,1529, 0, 0, 40000, 320,0.000000 }, - { 111,1530, 0, 0, 786, 786,0.000000 }, - {1531,1532, 0, 0, 20, 20,0.000000 }, - { 115,1533, 0, 0, 26, 26,0.000000 }, - {1534,1535, 0, 0, 166, 166,0.000000 }, - {1536,1537, 0, 0, 2280, 2280,0.000000 }, - {1538,1539, 0, 0, 280, 280,0.000000 }, - {1540, 339, 0, 0, 580, 580,0.000000 }, - {1541, 339, 0, 0, 4613, 4613,0.000000 }, - {1542,1543, 0, 0, 440, 440,0.000000 }, - {1544,1545, 0, 0, 153, 153,0.000000 }, - {1546,1547, 0, 0, 40000, 53,0.000000 }, - { 364, 365, 44, 0, 20, 20,0.000000 }, - { 129,1548, 48, 0, 66, 66,0.000000 }, - { 367, 368, 58, 0, 53, 53,0.000000 }, - { 129,1549, 60, 0, 73, 73,0.000000 }, - {1550,1551, 48, 0, 93, 93,0.000000 }, - { 132,1552, 43, 0, 13, 13,0.000000 }, - {1550,1551, 49, 0, 120, 120,0.000000 }, - {1553,1554, 43, 0, 26, 26,0.000000 }, - {1550,1551, 51, 0, 153, 153,0.000000 }, - { 134,1555, 43, 0, 146, 146,0.000000 }, - {1550,1551, 54, 0, 106, 106,0.000000 }, - {1550,1551, 57, 0, 100, 100,0.000000 }, - { 380, 381, 72, 0, 40000, 0,0.000000 }, - {1550,1551, 60, 0, 106, 106,0.000000 }, - {1556,1557, 70, 0, 246, 246,0.000000 }, - { 374, 375, 60, 0, 40000, 0,0.000000 }, - {1558,1559, 36, 0, 360, 360,0.000000 }, - {1560,1561, 65, 0, 113, 113,0.000000 }, - {1562,1563, 84, 0, 40000, 0,0.000000 }, - {1564,1565, 59, 0, 133, 133,0.000000 }, - {1566,1567, 84, 0, 40000, 0,0.000000 }, - {1568,1569, 35, 0, 53, 53,0.000000 }, - {1570,1571, 44, 0, 273, 273,0.000000 }, - {1572,1573, 67, 0, 66, 66,0.000000 }, - {1574,1575, 66, 0, 46, 46,0.000000 }, - { 145,1576, 59, 0, 13, 13,0.000000 }, - {1577,1578, 51, 0, 40, 40,0.000000 }, - {1579,1580, 45, 0, 40, 40,0.000000 }, - {1581,1582, 71, 0, 120, 120,0.000000 }, - { 149,1583, 60, 0, 180, 180,0.000000 }, - {1584,1585, 58, 0, 166, 166,0.000000 }, - {1586,1587, 53, 0, 140, 140,0.000000 }, - { 397,1588, 64, 0, 86, 86,0.000000 }, - {1589,1590, 71, 0, 13, 13,0.000000 }, - {1591,1592, 61, 0, 313, 313,0.000000 }, - {1593,1594, 61, 0, 513, 513,0.000000 }, - { 391, 392, 48, 0, 80, 80,0.000000 }, - { 391, 393, 48, 0, 80, 80,0.000000 }, - {1595,1596, 69, 0, 20, 20,0.000000 }, - { 159,1597, 68, 0, 20, 20,0.000000 }, - { 159,1597, 63, 0, 33, 33,0.000000 }, - {1598,1599, 74, 0, 333, 333,0.000000 }, - {1600,1601, 60, 0, 380, 380,0.000000 }, - {1602,1603, 80, 0, 60, 60,0.000000 }, - {1604,1605, 64, 0, 646, 646,0.000000 }, - {1606,1607, 69, 0, 33, 33,0.000000 }, - { 398, 399, 55, 0, 500, 500,0.000000 }, - {1608,1609, 75, 0, 346, 346,0.000000 }, - {1610,1611, 68, 0, 20, 20,0.000000 }, - {1612,1613, 48, 0, 46, 46,0.000000 }, - {1614,1615, 53, 0, 40, 40,0.000000 }, - {1616,1616, 0, 0, 40000, 873,0.000000 }, - {1617,1617, 0, 0, 40000, 446,0.000000 }, - {1618,1618, 0, 0, 1020, 1020,0.000000 }, - {1619,1619, 0, 0, 40000, 300,0.000000 }, - {1620,1620, 0, 0, 40000, 780,0.000000 }, - {1621,1621, 0, 0, 1400, 1400,0.000000 }, - {1622,1622, 0, 0, 40000, 480,0.000000 }, - {1623,1623, 0, 0, 40000, 566,0.000000 }, - {1624,1624, 0, 0, 3220, 3220,0.000000 }, - {1625,1625, 0, 0, 40000, 6,0.000000 }, - {1626,1626, 0, 0, 40000, 20,0.000000 }, - {1627,1627, 0, 0, 40000, 20,0.000000 }, - {1628,1628, 0, 0, 40000, 1180,0.000000 }, - {1629,1629, 0, 0, 40000, 20,0.000000 }, - {1630,1630, 0, 0, 40000, 6,0.000000 }, - {1631,1631, 0, 0, 40000, 6,0.000000 }, - {1632,1632, 0, 0, 40000, 280,0.000000 }, - {1633,1633, 0, 0, 40000, 6,0.000000 }, - {1634,1634, 0, 0, 40000, 6,0.000000 }, - {1635,1635, 0, 0, 40000, 6,0.000000 }, - {1636,1636, 0, 0, 340, 26,0.000000 }, - {1637,1637, 0, 0, 1000, 1000,0.000000 }, - {1638,1638, 0, 0, 40000, 200,0.000000 }, - {1639,1639, 0, 0, 460, 460,0.000000 }, - {1640,1640, 0, 0, 40000, 146,0.000000 }, - {1641,1641, 0, 0, 40000, 146,0.000000 }, - {1642,1642, 0, 0, 40000, 233,0.000000 }, - {1643,1643, 0, 0, 40000, 480,0.000000 }, - {1644,1644, 0, 0, 40000, 6,0.000000 }, - {1645,1645, 0, 0, 40000, 6,0.000000 }, - {1646,1646, 0, 0, 40000, 6,0.000000 }, - {1647,1647, 0, 0, 40000, 6,0.000000 }, - {1648,1648, 0, 0, 40000, 6,0.000000 }, - {1649,1649, 0, 0, 40000, 6,0.000000 }, - {1650,1650, 0, 0, 40000, 53,0.000000 }, - {1651,1651, 0, 0, 40000, 480,0.000000 }, - {1652,1652, 0, 0, 40000, 286,0.000000 }, - {1653,1653, 0, 0, 40000, 106,0.000000 }, - {1654,1654, 0, 0, 40000, 413,0.000000 }, - {1655,1655, 0, 0, 1213, 1213,0.000000 }, - {1656,1656, 0, 0, 513, 513,0.000000 }, - {1657,1657, 0, 0, 40000, 160,0.000000 }, - {1658,1658, 0, 0, 40000, 153,0.000000 }, - {1659,1659, 0, 0, 40000, 1973,0.000000 }, - {1660,1660, 0, 0, 40000, 3593,0.000000 }, - {1661,1661, 0, 0, 40000, 1120,0.000000 }, - {1662,1662, 0, 0, 620, 620,0.000000 }, - {1663,1663, 0, 0, 1740, 1740,0.000000 }, - {1664,1664, 0, 0, 940, 940,0.000000 }, - {1665,1665, 0, 0, 40000, 260,0.000000 }, - {1666,1666, 0, 0, 1900, 1900,0.000000 }, - {1667,1667, 0, 0, 40000, 426,0.000000 }, - {1668,1668, 12, 0, 66, 66,0.000000 }, - {1669,1669, 48, 0, 100, 100,0.000000 }, - { 736, 736, 52, 0, 80, 80,0.000000 }, - {1670,1670, 48, 0, 153, 153,0.000000 }, - {1670,1670, 36, 0, 146, 146,0.000000 }, - { 377, 377, 84, 0, 73, 73,0.000000 }, - { 730, 730, 95, 0, 600, 600,0.000000 }, - {1669,1669, 84, 0, 86, 86,0.000000 }, - { 755, 755, 20, 0, 200, 200,0.000000 }, - { 755, 755, 22, 0, 193, 193,0.000000 }, - { 755, 755, 24, 0, 200, 200,0.000000 }, - {1671,1671, 0, 0, 400, 400,0.000000 }, - {1672,1672, 0, 0, 460, 460,0.000000 }, - {1673,1673, 0, 0, 566, 566,0.000000 }, - {1674,1674, 0, 0, 40, 40,0.000000 }, - {1675,1675, 0, 0, 913, 913,0.000000 }, - {1676,1676, 0, 0, 940, 940,0.000000 }, - {1677,1677, 0, 0, 553, 553,0.000000 }, - {1678,1678, 0, 0, 653, 653,0.000000 }, - {1679,1679, 0, 0, 140, 140,0.000000 }, - {1680,1680, 0, 0, 440, 440,0.000000 }, - {1681,1681, 0, 0, 493, 493,0.000000 }, - {1682,1682, 0, 0, 40000, 213,0.000000 }, - {1683,1683, 0, 0, 246, 246,0.000000 }, - {1684,1684, 0, 0, 140, 140,0.000000 }, - {1685,1685, 0, 0, 880, 880,0.000000 }, - {1686,1686, 0, 0, 700, 700,0.000000 }, - {1687,1687, 0, 0, 40000, 0,0.000000 }, - {1688,1688, 0, 0, 40000, 6,0.000000 }, - {1689,1689, 0, 0, 86, 86,0.000000 }, - {1690,1690, 0, 0, 40000, 6,0.000000 }, - {1691,1691, 0, 0, 40000, 6,0.000000 }, - {1692,1692, 0, 0, 40000, 6,0.000000 }, - {1693,1693, 0, 0, 40000, 6,0.000000 }, - {1694,1694, 0, 0, 440, 440,0.000000 }, - {1695,1695, 0, 0, 440, 440,0.000000 }, - {1696,1696, 0, 0, 100, 0,0.000000 }, - {1697,1697, 0, 0, 1846, 1846,0.000000 }, - {1698,1698, 0, 0, 40, 40,0.000000 }, - {1699,1699, 0, 0, 6580, 6580,0.000000 }, - {1700,1700, 0, 0, 1846, 1846,0.000000 }, - {1701,1701, 0, 0, 1080, 1080,0.000000 }, - {1702,1702, 0, 0, 40000, 0,0.000000 }, - {1703,1703, 0, 0, 1020, 1020,0.000000 }, - {1704,1704, 0, 0, 40000, 53,0.000000 }, - {1705,1705, 0, 0, 40000, 0,0.000000 }, - {1706,1706, 0, 0, 40000, 0,0.000000 }, - {1707,1707, 0, 0, 40000, 53,0.000000 }, - {1708,1708, 0, 0, 40000, 0,0.000000 }, - {1709,1709, 0, 0, 40000, 26,0.000000 }, - {1710,1710, 0, 0, 626, 626,0.000000 }, - {1711,1711, 0, 0, 40000, 26,0.000000 }, - {1712,1712, 0, 0, 1226, 13,0.000000 }, - {1713,1713, 0, 0, 40000, 0,0.000000 }, - {1714,1714, 0, 0, 3980, 13,0.000000 }, - {1715,1715, 0, 0, 253, 253,0.000000 }, - {1716,1716, 0, 0, 940, 940,0.000000 }, - {1717,1717, 0, 0, 126, 126,0.000000 }, - {1718,1718, 0, 0, 3766, 13,0.000000 }, - {1719,1719, 0, 0, 660, 200,0.000000 }, - {1720,1720, 0, 0, 40000, 20,0.000000 }, - {1721,1721, 0, 0, 40000, 20,0.000000 }, - {1722,1722, 0, 0, 40000, 146,0.000000 }, - {1723,1723, 0, 0, 40000, 26,0.000000 }, - {1724,1724, 0, 0, 40000, 140,0.000000 }, - {1725,1725, 0, 0, 260, 260,0.000000 }, - {1726,1726, 0, 0, 40000, 0,0.000000 }, - {1727,1727, 0, 0, 126, 0,0.000000 }, - {1728,1728, 0, 0, 386, 6,0.000000 }, - {1729,1729, 0, 0, 40000, 33,0.000000 }, - {1730,1730, 0, 0, 126, 33,0.000000 }, - {1731,1731, 0, 0, 1580, 1580,0.000000 }, - {1732,1732, 0, 0, 40000, 6,0.000000 }, - {1733,1733, 0, 0, 40000, 6,0.000000 }, - {1734,1734, 0, 0, 40000, 6,0.000000 }, - {1735,1735, 0, 0, 40000, 13,0.000000 }, - {1736,1736, 0, 0, 40000, 13,0.000000 }, - {1737,1737, 0, 0, 40000, 20,0.000000 }, - {1738,1738, 0, 0, 40000, 13,0.000000 }, - {1739,1739, 0, 0, 40000, 13,0.000000 }, - {1740,1740, 0, 0, 40000, 73,0.000000 }, - {1741,1741, 0, 0, 40000, 6,0.000000 }, - {1742,1742, 0, 0, 40000, 6,0.000000 }, - {1743,1743, 0, 0, 40000, 20,0.000000 }, - {1744,1744, 0, 0, 993, 993,0.000000 }, - {1745,1745, 0, 0, 40000, 20,0.000000 }, - {1746,1746, 0, 0, 40000, 0,0.000000 }, - {1747,1747, 0, 0, 40000, 0,0.000000 }, - {1748,1748, 0, 0, 933, 6,0.000000 }, - {1749,1749, 0, 0, 40000, 20,0.000000 }, - {1750,1750, 0, 0, 40000, 6,0.000000 }, - {1751,1751, 0, 0, 40000, 13,0.000000 }, - {1752,1752, 0, 0, 40000, 26,0.000000 }, - {1753,1753, 0, 0, 40000, 0,0.000000 }, - {1754,1754, 0, 0, 1793, 1793,0.000000 }, - {1755,1755, 0, 0, 40000, 106,0.000000 }, - {1756,1756, 0, 0, 40000, 46,0.000000 }, - {1757,1757, 0, 0, 40000, 33,0.000000 }, - {1758,1758, 0, 0, 40000, 286,0.000000 }, - {1759,1759, 0, 0, 40000, 906,0.000000 }, - {1760,1760, 0, 0, 40000, 220,0.000000 }, - {1761,1761, 0, 0, 40000, 53,0.000000 }, - {1762,1762, 0, 0, 40000, 40,0.000000 }, - {1763,1763, 0, 0, 3446, 3446,0.000000 }, - {1764,1764, 0, 0, 860, 13,0.000000 }, - {1765,1765, 0, 0, 513, 513,0.000000 }, - {1766,1766, 0, 0, 1846, 1846,0.000000 }, - {1767,1767, 0, 0, 973, 973,0.000000 }, - {1768,1768, 0, 0, 40000, 366,0.000000 }, - {1769,1769, 0, 0, 1426, 1426,0.000000 }, - {1770,1770, 0, 0, 40000, 686,0.000000 }, - {1771,1771, 0, 0, 1060, 1060,0.000000 }, - {1772,1772, 0, 0, 13, 13,0.000000 }, - {1773,1773, 0, 0, 380, 380,0.000000 }, - {1774,1774, 0, 0, 146, 146,0.000000 }, - {1775,1775, 0, 0, 166, 166,0.000000 }, - {1776,1776, 0, 0, 40000, 6,0.000000 }, - {1777,1777, 0, 0, 40000, 0,0.000000 }, - {1778,1778, 0, 0, 40000, 66,0.000000 }, - {1779,1779, 0, 0, 1473, 1473,0.000000 }, - {1780,1780, 0, 0, 113, 113,0.000000 }, - {1781,1781, 0, 0, 353, 353,0.000000 }, - {1782,1782, 0, 0, 46, 46,0.000000 }, - {1783,1783, 0, 0, 86, 86,0.000000 }, - {1784,1784, 0, 0, 60, 60,0.000000 }, - {1785,1785, 0, 0, 2280, 2280,0.000000 }, - {1786,1786, 0, 0, 366, 366,0.000000 }, - {1787,1787, 0, 0, 1713, 1713,0.000000 }, - {1788,1788, 0, 0, 206, 206,0.000000 }, - {1789,1789, 0, 0, 40000, 6,0.000000 }, - {1790,1790, 0, 0, 40000, 0,0.000000 }, - {1791,1791, 0, 0, 40000, 553,0.000000 }, - {1792,1792, 0, 0, 160, 160,0.000000 }, - {1793,1793, 48, 0, 46, 46,0.000000 }, - {1794,1794, 48, 0, 13, 13,0.000000 }, - {1795,1795, 60, 0, 46, 46,0.000000 }, - {1796,1796, 60, 0, 33, 33,0.000000 }, - {1797,1797, 70, 0, 33, 33,0.000000 }, - {1798,1798, 51, 0, 160, 160,0.000000 }, - {1799,1799, 60, 0, 40, 40,0.000000 }, - {1798,1798, 54, 0, 140, 140,0.000000 }, - {1800,1800, 60, 0, 53, 53,0.000000 }, - {1798,1798, 56, 0, 140, 140,0.000000 }, - {1801,1801, 60, 0, 300, 300,0.000000 }, - {1798,1798, 61, 0, 166, 166,0.000000 }, - {1798,1798, 63, 0, 166, 166,0.000000 }, - {1802,1802, 48, 0, 300, 300,0.000000 }, - {1798,1798, 68, 0, 133, 133,0.000000 }, - {1803,1803, 60, 0, 393, 393,0.000000 }, - {1804,1804, 60, 0, 313, 313,0.000000 }, - {1805,1805, 66, 0, 100, 100,0.000000 }, - {1806,1806, 60, 0, 306, 306,0.000000 }, - { 379, 379, 59, 0, 40, 40,0.000000 }, - {1802,1802, 64, 0, 306, 306,0.000000 }, - {1807,1807, 48, 0, 566, 566,0.000000 }, - {1808,1808, 56, 0, 26, 26,0.000000 }, - {1809,1809, 53, 0, 73, 73,0.000000 }, - {1810,1810, 65, 0, 13, 13,0.000000 }, - {1811,1811, 49, 0, 86, 86,0.000000 }, - {1811,1811, 43, 0, 86, 86,0.000000 }, - { 386, 386, 65, 0, 86, 86,0.000000 }, - { 386, 386, 60, 0, 86, 86,0.000000 }, - {1812,1812, 70, 0, 80, 80,0.000000 }, - {1812,1812, 65, 0, 100, 100,0.000000 }, - {1813,1813, 60, 0, 40, 40,0.000000 }, - {1814,1814, 60, 0, 33, 33,0.000000 }, - {1815,1815, 56, 0, 93, 93,0.000000 }, - {1816,1816, 53, 0, 280, 280,0.000000 }, - {1817,1817, 60, 0, 60, 60,0.000000 }, - {1818,1818, 48, 0, 180, 180,0.000000 }, - {1819,1819, 69, 0, 20, 20,0.000000 }, - { 328, 328, 67, 0, 20, 20,0.000000 }, - { 328, 328, 62, 0, 20, 20,0.000000 }, - {1820,1820, 65, 0, 220, 220,0.000000 }, - {1821,1821, 60, 0, 220, 220,0.000000 }, - {1822,1822, 63, 0, 26, 26,0.000000 }, - {1823,1823, 63, 0, 606, 606,0.000000 }, - {1824,1824, 67, 0, 86, 86,0.000000 }, - {1825,1825, 60, 0, 300, 300,0.000000 }, - {1825,1825, 72, 0, 273, 273,0.000000 }, - { 401, 401, 62, 0, 6, 6,0.000000 }, - {1826,1826, 48, 0, 13, 13,0.000000 }, - {1827,1827, 53, 0, 213, 213,0.000000 }, - {1828,1828, 60, 0, 93, 93,0.000000 }, - {1829,1829, 60, 0, 40, 40,0.000000 }, - {1830,1830, 60, 0, 20, 20,0.000000 }, - {1831,1831, 60, 0, 46, 46,0.000000 }, - {1832,1832, 0, 0, 126, 0,0.000000 }, - {1833,1833, 0, 0, 1240, 1240,0.000000 }, - {1834,1834, 0, 0, 433, 433,0.000000 }, - {1835,1835, 0, 0, 40000, 0,0.000000 }, - {1836,1836, 0, 0, 40000, 153,0.000000 }, - {1837,1837, 0, 0, 146, 106,0.000000 }, - {1838,1838, 0, 0, 126, 126,0.000000 }, - {1839,1839, 0, 0, 1740, 1740,0.000000 }, - {1840,1840, 0, 0, 440, 13,0.000000 }, - {1841,1841, 0, 0, 546, 546,0.000000 }, - {1842,1842, 0, 0, 1420, 1420,0.000000 }, - { 525, 525, 0, 0, 1220, 1220,0.000000 }, - {1843,1843, 0, 0, 40000, 140,0.000000 }, - {1844,1844, 0, 0, 3873, 3873,0.000000 }, - {1845,1845, 0, 0, 546, 546,0.000000 }, - {1846,1846, 0, 0, 333, 333,0.000000 }, - {1847,1847, 0, 0, 4933, 4933,0.000000 }, - {1848,1848, 0, 0, 126, 0,0.000000 }, - {1849,1849, 0, 0, 380, 380,0.000000 }, - {1850,1850, 0, 0, 40000, 6,0.000000 }, - {1851,1851, 0, 0, 273, 273,0.000000 }, - {1852,1852, 0, 0, 233, 233,0.000000 }, - {1853,1853, 0, 0, 40000, 233,0.000000 }, - {1854,1854, 0, 0, 1466, 6,0.000000 }, - {1855,1855, 0, 0, 1380, 1380,0.000000 }, - {1856,1856, 0, 0, 40000, 106,0.000000 }, - {1857,1857, 0, 0, 40000, 133,0.000000 }, - {1858,1858, 0, 0, 913, 913,0.000000 }, - {1859,1859, 0, 0, 60, 60,0.000000 }, - {1860,1860, 0, 0, 40000, 6,0.000000 }, - {1861,1861, 0, 0, 866, 866,0.000000 }, - {1862,1862, 0, 0, 4726, 4726,0.000000 }, - {1863,1863, 0, 0, 40, 40,0.000000 }, - {1864,1864, 0, 0, 1793, 1793,0.000000 }, - {1865,1865, 0, 0, 246, 246,0.000000 }, - {1866,1866, 0, 0, 40000, 133,0.000000 }, - {1867,1867, 0, 0, 2006, 2006,0.000000 }, - {1868,1868, 0, 0, 140, 140,0.000000 }, - {1869,1869, 0, 0, 40000, 106,0.000000 }, - {1870,1870, 0, 0, 460, 460,0.000000 }, - {1871,1871, 0, 0, 146, 146,0.000000 }, - {1872,1872, 0, 0, 273, 273,0.000000 }, - {1873,1873, 0, 0, 40000, 46,0.000000 }, - {1874,1874, 41, 0, 120, 120,0.000000 }, - {1875,1875, 70, 0, 13, 13,0.000000 }, - {1876,1876, 60, 0, 40, 40,0.000000 }, - {1877,1877, 80, 0, 13, 13,0.000000 }, - {1878,1878, 84, 0, 20, 20,0.000000 }, - {1879,1879, 72, 0, 133, 133,0.000000 }, - {1880,1880, 84, 0, 266, 266,0.000000 }, - { 128, 128, 70, 0, 13, 13,0.000000 }, - { 132, 132, 60, 0, 13, 13,0.000000 }, - {1881,1882, 0, 0, 40000, 173,0.000000 }, - {1883,1883, 0, 0, 260, 260,0.000000 }, - {1884,1885, 0, 0, 40000, 6,0.000000 }, - {1886,1887, 0, 0, 40000, 20,0.000000 }, - {1888,1889, 0, 0, 40000, 6,0.000000 }, - {1890,1890, 0, 0, 1020, 53,0.000000 }, - {1891,1891, 0, 0, 40000, 100,0.000000 }, - {1892,1892, 0, 0, 786, 340,0.000000 }, - {1893,1893, 0, 0, 40000, 140,0.000000 }, - {1894,1894, 0, 0, 86, 86,0.000000 }, - {1895,1895, 0, 0, 80, 40,0.000000 }, - {1896,1896, 0, 0, 40000, 86,0.000000 }, - {1897,1897, 0, 0, 173, 173,0.000000 }, - {1898,1898, 0, 0, 886, 886,0.000000 }, - {1899,1899, 0, 0, 466, 466,0.000000 }, - {1900,1900, 0, 0, 40000, 106,0.000000 }, - {1901,1901, 0, 0, 40000, 66,0.000000 }, - {1902,1902, 0, 0, 40000, 13,0.000000 }, - {1903,1903, 0, 0, 60, 60,0.000000 }, - {1904,1904, 0, 0, 1226, 1226,0.000000 }, - {1905,1905, 0, 0, 280, 280,0.000000 }, - {1906,1906, 0, 0, 40000, 153,0.000000 }, - {1907,1907, 0, 0, 40000, 173,0.000000 }, - {1908,1908, 0, 0, 40000, 340,0.000000 }, - {1909,1909, 0, 0, 166, 166,0.000000 }, - { 501, 501, 0, 0, 86, 86,0.000000 }, - {1910,1910, 0, 0, 40000, 20,0.000000 }, - {1911,1911, 0, 0, 20, 20,0.000000 }, - {1912,1912, 0, 0, 600, 600,0.000000 }, - {1913,1913, 0, 0, 40000, 2393,0.000000 }, - {1914,1914, 0, 0, 166, 166,0.000000 }, - { 511, 511, 0, 0, 586, 586,0.000000 }, - {1915,1915, 0, 0, 73, 73,0.000000 }, - {1910,1910, 60, 0, 40000, 26,0.000000 }, - { 511, 511, 72, 0, 493, 493,0.000000 }, - {1915,1915, 84, 0, 60, 60,0.000000 }, - {1916,1916, 0, 0, 2080, 2080,0.000000 }, - {1917,1917, 0, 0, 593, 593,0.000000 }, - {1918,1918, 0, 0, 600, 600,0.000000 }, - {1919,1919, 0, 0, 940, 940,0.000000 }, - {1920,1920, 0, 0, 940, 940,0.000000 }, - {1921,1921, 0, 0, 940, 940,0.000000 }, - {1922,1922, 0, 0, 853, 853,0.000000 }, - {1923,1923, 0, 0, 893, 893,0.000000 }, - {1924,1924, 0, 0, 40000, 73,0.000000 }, - {1925,1925, 0, 0, 40000, 33,0.000000 }, - {1926,1926, 0, 0, 40000, 20,0.000000 }, - {1927,1927, 0, 0, 40000, 0,0.000000 }, - {1928,1928, 0, 0, 40000, 193,0.000000 }, - {1929,1929, 0, 0, 40000, 133,0.000000 }, - {1930,1930, 0, 0, 40000, 153,0.000000 }, - {1931,1931, 0, 0, 1146, 1146,0.000000 }, - {1932,1932, 0, 0, 960, 960,0.000000 }, - {1933,1933, 0, 0, 2406, 2406,0.000000 }, - {1934,1934, 0, 0, 2406, 2406,0.000000 }, - {1935,1935, 0, 0, 40000, 0,0.000000 }, - {1936,1936, 0, 0, 40000, 6,0.000000 }, - {1937,1937, 0, 0, 40000, 0,0.000000 }, - {1938,1938, 0, 0, 40000, 0,0.000000 }, - {1939,1939, 0, 0, 40000, 26,0.000000 }, - {1940,1940, 0, 0, 1426, 1426,0.000000 }, - {1941,1941, 0, 0, 40000, 766,0.000000 }, - {1942,1942, 0, 0, 40000, 453,0.000000 }, - {1943,1943, 0, 0, 40000, 486,0.000000 }, - {1944,1944, 0, 0, 40000, 106,0.000000 }, - {1945,1945, 0, 0, 2273, 2273,0.000000 }, - {1946,1946, 0, 0, 40000, 33,0.000000 }, - {1947,1947, 0, 0, 1226, 1226,0.000000 }, - {1948,1948, 0, 0, 40000, 6,0.000000 }, - {1949,1949, 0, 0, 40000, 1966,0.000000 }, - {1950,1950, 0, 0, 1153, 1153,0.000000 }, - {1951,1951, 0, 0, 40000, 6,0.000000 }, - {1952,1952, 0, 0, 1473, 1473,0.000000 }, - {1953,1953, 0, 0, 40000, 20,0.000000 }, - {1954,1954, 0, 0, 466, 33,0.000000 }, - {1955,1955, 0, 0, 833, 833,0.000000 }, - {1956,1956, 0, 0, 40000, 0,0.000000 }, - {1957,1957, 0, 0, 40000, 33,0.000000 }, - {1958,1958, 0, 0, 40000, 126,0.000000 }, - {1959,1959, 0, 0, 40000, 33,0.000000 }, - {1960,1960, 0, 0, 280, 280,0.000000 }, - {1961,1961, 0, 0, 40000, 266,0.000000 }, - {1962,1962, 0, 0, 40000, 46,0.000000 }, - {1963,1963, 0, 0, 40000, 266,0.000000 }, - {1964,1964, 0, 0, 40000, 0,0.000000 }, - {1965,1965, 0, 0, 40000, 113,0.000000 }, - {1966,1966, 0, 0, 800, 800,0.000000 }, - {1967,1967, 0, 0, 1206, 1206,0.000000 }, - {1968,1968, 0, 0, 1080, 1080,0.000000 }, - {1969,1969, 0, 0, 40000, 13,0.000000 }, - {1970,1970, 0, 0, 546, 546,0.000000 }, - {1971,1971, 0, 0, 40000, 6,0.000000 }, - {1972,1972, 0, 0, 40000, 20,0.000000 }, - {1973,1973, 0, 0, 1233, 20,0.000000 }, - {1974,1974, 0, 0, 40000, 0,0.000000 }, - {1975,1975, 0, 0, 40000, 0,0.000000 }, - {1976,1976, 0, 0, 466, 6,0.000000 }, - {1977,1977, 0, 0, 206, 206,0.000000 }, - {1978,1978, 0, 0, 40000, 6,0.000000 }, - {1979,1979, 0, 0, 40000, 6,0.000000 }, - {1980,1980, 0, 0, 40000, 6,0.000000 }, - {1981,1981, 0, 0, 40000, 6,0.000000 }, - {1982,1982, 0, 0, 40000, 0,0.000000 }, - {1983,1983, 0, 0, 40000, 0,0.000000 }, - {1984,1984, 0, 0, 40000, 0,0.000000 }, - {1985,1985, 0, 0, 40000, 180,0.000000 }, - {1986,1986, 0, 0, 40000, 53,0.000000 }, - {1987,1987, 0, 0, 40000, 53,0.000000 }, - {1988,1988, 0, 0, 40000, 6,0.000000 }, - {1989,1989, 0, 0, 40000, 6,0.000000 }, - {1990,1990, 0, 0, 100, 100,0.000000 }, - {1991,1991, 0, 0, 40000, 73,0.000000 }, - {1992,1992, 0, 0, 60, 60,0.000000 }, - {1993,1993, 0, 0, 40000, 0,0.000000 }, - {1994,1994, 0, 0, 40000, 0,0.000000 }, - {1995,1995, 0, 0, 40000, 0,0.000000 }, - {1996,1996, 0, 0, 40000, 6,0.000000 }, - {1997,1997, 0, 0, 40000, 0,0.000000 }, - {1998,1998, 0, 0, 40000, 0,0.000000 }, - {1999,1999, 0, 0, 40000, 0,0.000000 }, - {2000,2000, 0, 0, 40000, 233,0.000000 }, - {2001,2001, 0, 0, 40000, 233,0.000000 }, - {2002,2002, 0, 0, 620, 620,0.000000 }, - {2003,2003, 0, 0, 1740, 1740,0.000000 }, - {2004,2004, 0, 0, 1153, 1153,0.000000 }, - {2005,2005, 0, 0, 920, 920,0.000000 }, - {2006,2006, 0, 0, 153, 153,0.000000 }, - {2007,2007, 0, 0, 526, 526,0.000000 }, - {2008,2008, 0, 0, 40000, 6,0.000000 }, - {2009,2009, 0, 0, 40000, 40,0.000000 }, - {2010,2010, 0, 0, 40000, 53,0.000000 }, - {2011,2011, 0, 0, 40000, 160,0.000000 }, - {2012,2012, 0, 0, 40000, 6,0.000000 }, - {2013,2013, 0, 0, 1046, 1046,0.000000 }, - {2014,2014, 0, 0, 513, 513,0.000000 }, - {2015,2015, 0, 0, 40, 40,0.000000 }, - {2016,2016, 0, 0, 40, 40,0.000000 }, - {2017,2017, 0, 0, 93, 93,0.000000 }, - {2018,2018, 0, 0, 66, 66,0.000000 }, - {2019,2019, 0, 0, 13, 13,0.000000 }, - {2020,2020, 0, 0, 300, 300,0.000000 }, - {2021,2021, 0, 0, 40, 40,0.000000 }, - {2022,2022, 0, 0, 586, 586,0.000000 }, - {2023,2023, 0, 0, 260, 260,0.000000 }, - {2024,2024, 0, 0, 2406, 2406,0.000000 }, - {2025,2025, 0, 0, 126, 126,0.000000 }, - {2026,2026, 0, 0, 1220, 1220,0.000000 }, - {2027,2027, 0, 0, 386, 386,0.000000 }, - { 352, 352, 51, 0, 40000, 0,0.000000 }, - {2028,2028, 35, 0, 106, 106,0.000000 }, - {2028,2028, 36, 0, 93, 93,0.000000 }, - {2029,2029, 47, 0, 13, 13,0.000000 }, - {2030,2030, 38, 0, 106, 106,0.000000 }, - {2019,2019, 39, 0, 20, 20,0.000000 }, - {2031,2031, 45, 0, 80, 80,0.000000 }, - { 492, 492, 41, 0, 26, 26,0.000000 }, - {2032,2032, 42, 0, 33, 33,0.000000 }, - {2033,2033, 44, 0, 160, 160,0.000000 }, - { 492, 492, 48, 0, 40, 40,0.000000 }, - {2034,2034, 46, 0, 600, 600,0.000000 }, - { 492, 492, 53, 0, 26, 26,0.000000 }, - { 167, 167, 56, 0, 160, 160,0.000000 }, - {2035,2035, 61, 0, 93, 93,0.000000 }, - {2036,2036, 56, 0, 353, 353,0.000000 }, - {2037,2037, 60, 0, 40, 40,0.000000 }, - { 144, 144, 59, 0, 40, 40,0.000000 }, - {2038,2038, 59, 0, 13, 13,0.000000 }, - { 169, 169, 51, 0, 40, 40,0.000000 }, - { 169, 169, 45, 0, 40, 40,0.000000 }, - {2039,2039, 72, 0, 126, 126,0.000000 }, - {2040,2040, 60, 0, 153, 153,0.000000 }, - {2041,2041, 58, 0, 40, 40,0.000000 }, - {2042,2042, 53, 0, 40, 40,0.000000 }, - {2043,2043, 73, 0, 26, 26,0.000000 }, - { 158, 158, 75, 0, 20, 20,0.000000 }, - {2044,2044, 0, 0, 1226, 1226,0.000000 }, - {2045,2045, 0, 0, 493, 493,0.000000 }, - {2046,2046, 0, 0, 620, 620,0.000000 }, - {2047,2047, 0, 0, 280, 280,0.000000 }, - {2048,2048, 0, 0, 260, 260,0.000000 }, - {2049,2049, 0, 0, 40000, 1093,0.000000 }, - {2050,2050, 0, 0, 40000, 233,0.000000 }, - {2051,2051, 0, 0, 120, 120,0.000000 }, - {2052,2052, 0, 0, 40000, 926,0.000000 }, - {2053,2053, 0, 0, 40000, 926,0.000000 }, - {2054,2054, 0, 0, 40000, 233,0.000000 }, - {2055,2055, 0, 0, 40000, 280,0.000000 }, - {2056,2056, 0, 0, 40000, 6,0.000000 }, - {2057,2057, 0, 0, 40000, 153,0.000000 }, - {2058,2058, 0, 0, 286, 286,0.000000 }, - {2059,2059, 0, 0, 286, 286,0.000000 }, - {2060,2060, 0, 0, 40000, 0,0.000000 }, - {2061,2061, 0, 0, 680, 680,0.000000 }, - {2062,2062, 0, 0, 280, 280,0.000000 }, - {2063,2063, 0, 0, 40000, 200,0.000000 }, - {2064,2064, 0, 0, 40, 40,0.000000 }, - {2065,2065, 0, 0, 1580, 1580,0.000000 }, - {2066,2066, 0, 0, 140, 133,0.000000 }, - {2067,2067, 0, 0, 40000, 213,0.000000 }, - {2068,2068, 0, 0, 613, 613,0.000000 }, - {2069,2069, 0, 0, 293, 293,0.000000 }, - {2070,2070, 0, 0, 160, 160,0.000000 }, - {2071,2071, 0, 0, 146, 13,0.000000 }, - {2072,2072, 0, 0, 40000, 6,0.000000 }, - {2073,2073, 0, 0, 40000, 133,0.000000 }, - {2074,2074, 0, 0, 40000, 140,0.000000 }, - {2075,2075, 0, 0, 40000, 66,0.000000 }, - {2076,2076, 0, 0, 40000, 40,0.000000 }, - {2077,2077, 0, 0, 40000, 153,0.000000 }, - {2078,2078, 0, 0, 593, 593,0.000000 }, - {2079,2079, 0, 0, 40000, 40,0.000000 }, - {2080,2080, 0, 0, 4480, 4480,0.000000 }, - {2081,2081, 0, 0, 3600, 313,0.000000 }, - {2082,2082, 0, 0, 40000, 413,0.000000 }, - {2083,2083, 0, 0, 40000, 566,0.000000 }, - {2084,2084, 0, 0, 8420, 80,0.000000 }, - {2085,2085, 0, 0, 40000, 926,0.000000 }, - {2086,2086, 0, 0, 40000, 853,0.000000 }, - {2087,2087, 0, 0, 40000, 853,0.000000 }, - {2088,2088, 0, 0, 40000, 853,0.000000 }, - {2089,2089, 0, 0, 40000, 873,0.000000 }, - {2090,2090, 0, 0, 40000, 1780,0.000000 }, - {2091,2091, 0, 0, 40000, 1673,0.000000 }, - {2092,2092, 0, 0, 4026, 4026,0.000000 }, - {2093,2093, 0, 0, 1773, 153,0.000000 }, - {2094,2094, 0, 0, 1446, 1446,0.000000 }, - {2095,2095, 0, 0, 633, 633,0.000000 }, - {2096,2096, 0, 0, 333, 333,0.000000 }, - {2097,2097, 0, 0, 193, 193,0.000000 }, - {2098,2098, 0, 0, 86, 86,0.000000 }, - {2099,2099, 0, 0, 246, 246,0.000000 }, - {2100,2100, 0, 0, 40000, 6,0.000000 }, - {2101,2101, 0, 0, 40000, 6,0.000000 }, - {2102,2102, 0, 0, 313, 313,0.000000 }, - {2103,2103, 0, 0, 160, 160,0.000000 }, - {2104,2104, 0, 0, 46, 46,0.000000 }, - {2105,2105, 0, 0, 100, 100,0.000000 }, - {2106,2106, 0, 0, 2313, 2313,0.000000 }, - {2107,2107, 0, 0, 306, 306,0.000000 }, - {2108,2108, 0, 0, 40000, 2180,0.000000 }, - {2109,2109, 0, 0, 40000, 133,0.000000 }, - {2110,2110, 0, 0, 40000, 126,0.000000 }, - {2111,2111, 0, 0, 40000, 146,0.000000 }, - { 752, 752, 60, 0, 40, 40,0.000000 }, - { 755, 755, 12, 0, 160, 160,0.000000 }, - {2112,2112, 89, 0, 13, 13,0.000000 }, - {2113,2113, 89, 0, 206, 206,0.000000 }, - { 755, 755, 14, 0, 160, 160,0.000000 }, - { 755, 755, 16, 0, 160, 160,0.000000 }, - {2114,2114, 84, 0, 513, 513,0.000000 }, - { 755, 755, 19, 0, 160, 160,0.000000 }, - {2115,2115, 38, 0, 60, 60,0.000000 }, - {2116,2116, 36, 0, 20, 20,0.000000 }, - { 755, 755, 28, 0, 193, 193,0.000000 }, - { 755, 755, 26, 0, 200, 200,0.000000 }, - { 755, 755, 35, 0, 200, 200,0.000000 }, - { 755, 755, 30, 0, 193, 193,0.000000 }, - {2117,2117, 60, 0, 73, 73,0.000000 }, - {2104,2104, 60, 0, 40, 40,0.000000 }, - {2104,2104, 55, 0, 46, 46,0.000000 }, - { 730, 730, 94, 0, 626, 626,0.000000 }, - {2118,2118, 0, 0, 280, 280,0.000000 }, - {2119,2119, 0, 0, 1446, 1446,0.000000 }, - {2120,2120, 0, 0, 40000, 53,0.000000 }, - {2121,2121, 0, 0, 40000, 20,0.000000 }, - {2122,2122, 0, 0, 40000, 20,0.000000 }, - {2123,2123, 0, 0, 3106, 3106,0.000000 }, - {2124,2124, 0, 0, 40, 66,0.000000 }, - {2125,2125, 0, 0, 40000, 106,0.000000 }, - {2126,2126, 0, 0, 40000, 6,0.000000 }, - {2127,2127, 0, 0, 40000, 13,0.000000 }, - {2128,2128, 0, 0, 40000, 6,0.000000 }, - {2129,2129, 0, 0, 40000, 6,0.000000 }, - {2130,2130, 0, 0, 40000, 6,0.000000 }, - {2131,2131, 0, 0, 40000, 13,0.000000 }, - {2132,2132, 0, 0, 40000, 6,0.000000 }, - {2133,2133, 0, 0, 2060, 13,0.000000 }, - {2134,2134, 0, 0, 40000, 53,0.000000 }, - {2135,2135, 0, 0, 2886, 2886,0.000000 }, - {2136,2136, 0, 0, 40000, 126,0.000000 }, - {2137,2137, 0, 0, 5280, 100,0.000000 }, - {2138,2138, 0, 0, 140, 140,0.000000 }, - {2139,2139, 0, 0, 4553, 20,0.000000 }, - {2140,2140, 0, 0, 513, 513,0.000000 }, - {2141,2141, 60, 0, 40, 40,0.000000 }, - {2141,2141, 44, 0, 40, 40,0.000000 }, - {2142,2142, 47, 0, 40, 40,0.000000 }, - {2143,2143, 47, 0, 60, 60,0.000000 }, - {2144,2144, 62, 0, 606, 606,0.000000 }, - {2145,2145, 93, 0, 226, 226,0.000000 }, - {2146,2146, 50, 0, 80, 80,0.000000 }, - {2145,2145, 40, 0, 420, 420,0.000000 }, - {2147,2147, 60, 0, 20, 20,0.000000 }, - { 898, 898, 60, 0, 46, 46,0.000000 }, - {2147,2147, 57, 0, 20, 20,0.000000 }, - { 900, 900, 42, 0, 193, 193,0.000000 }, - { 900, 900, 38, 0, 193, 193,0.000000 }, - { 908, 908, 88, 0, 33, 33,0.000000 }, - {2148,2148, 0, 0, 1553, 1553,0.000000 }, - {2149,2149, 0, 0, 40000, 6,0.000000 }, - {2150,2150, 0, 0, 993, 993,0.000000 }, - {2151,2151, 0, 0, 40000, 26,0.000000 }, - {2152,2152, 0, 0, 29720, 80,0.000000 }, - {2153,2153, 0, 0, 40000, 306,0.000000 }, - {2154,2154, 0, 0, 700, 700,0.000000 }, - {2155,2155, 0, 0, 880, 880,0.000000 }, - {2156,2156, 0, 0, 40000, 6,0.000000 }, - {2157,2157, 0, 0, 1046, 1046,0.000000 }, - {2158,2158, 0, 0, 100, 100,0.000000 }, - {2159,2159, 0, 0, 40, 40,0.000000 }, - { 136, 136, 0, 0, 640, 640,0.000000 }, - { 168, 168, 0, 0, 40, 40,0.000000 }, - { 164, 164, 0, 0, 1220, 1220,0.000000 }, - { 167, 167, 0, 0, 160, 160,0.000000 }, - {2160,2160, 65, 0, 40, 40,0.000000 }, - {2161,2161, 21, 0, 200, 200,0.000000 }, - {2162, 173, 0, 0, 1513, 1513,0.000000 }, - {2163,2164, 0, 0, 653, 653,0.000000 }, - {2165,2166, 0, 0, 633, 633,0.000000 }, - {2167,2168, 0, 0, 913, 913,0.000000 }, - {2169,2170, 0, 0, 300, 300,0.000000 }, - {2171,2172, 0, 0, 1773, 1773,0.000000 }, - {2173,2174, 0, 0, 40000, 306,0.000000 }, - {2175,2174, 0, 0, 40000, 433,0.000000 }, - {2176, 299, 0, 0, 40000, 66,0.000000 }, - {2177,2178, 0, 0, 40000, 246,0.000000 }, - {2179,2180, 0, 0, 40000, 300,0.000000 }, - {2181,2182, 0, 0, 40000, 233,0.000000 }, - {2183,2184, 0, 0, 1740, 1740,0.000000 }, - { 127, 127, 65, 0, 66, 66,0.000000 }, - { 127, 127, 72, 0, 46, 46,0.000000 }, - { 364, 365, 52, 0, 20, 20,0.000000 }, - {2185,2186, 60, 0, 80, 80,0.000000 }, - {1550,1551, 47, 0, 100, 100,0.000000 }, - {1556,1557, 76, 0, 253, 253,0.000000 }, - { 374, 375, 84, 0, 40000, 0,0.000000 }, - {1564,1565, 83, 0, 73, 73,0.000000 }, - {1568,1569, 24, 0, 40, 40,0.000000 }, - {1556,1557, 77, 0, 253, 253,0.000000 }, - {1572,1573, 60, 0, 80, 80,0.000000 }, - {1574,1575, 65, 0, 46, 46,0.000000 }, - { 391, 392, 44, 0, 80, 80,0.000000 }, - { 391, 393, 40, 0, 40, 40,0.000000 }, - {1606,1607, 72, 0, 33, 33,0.000000 }, - { 398, 399, 73, 0, 400, 400,0.000000 }, - {1608,1609, 70, 0, 353, 353,0.000000 }, - {2187,2187, 0, 0, 40000, 140,0.000000 }, - {2188,2188, 0, 0, 40000, 153,0.000000 }, - {2189,2189, 0, 0, 453, 453,0.000000 }, - {2190,2190, 0, 0, 1300, 1300,0.000000 }, - {2191,2191, 0, 0, 46, 46,0.000000 }, - {2192,2192, 0, 0, 40000, 186,0.000000 }, - {2193,2193, 0, 0, 80, 80,0.000000 }, - {2194,2194, 0, 0, 40000, 6,0.000000 }, - {2195,2195, 0, 0, 186, 186,0.000000 }, - {2196,2196, 0, 0, 40000, 0,0.000000 }, - {2197,2197, 0, 0, 40000, 0,0.000000 }, - {2198,2198, 0, 0, 166, 0,0.000000 }, - {2199,2199, 0, 0, 40, 40,0.000000 }, - {2200,2200, 0, 0, 1740, 1740,0.000000 }, - { 528, 528, 0, 0, 140, 140,0.000000 }, - {2201,2201, 0, 0, 40000, 53,0.000000 }, - {2202,2202, 0, 0, 40, 40,0.000000 }, - {2203,2203, 0, 0, 80, 80,0.000000 }, - {2204,2204, 41, 0, 46, 46,0.000000 }, - {2205,2205, 84, 0, 40, 40,0.000000 }, - {2206,2206, 72, 0, 133, 133,0.000000 }, - { 741, 741, 48, 0, 133, 133,0.000000 }, - {2207,2207, 0, 0, 40, 40,0.000000 }, - {2208,2208, 0, 0, 940, 940,0.000000 }, - {2209,2209, 0, 0, 40000, 213,0.000000 }, - {2210,2210, 0, 0, 866, 866,0.000000 }, - {2211,2211, 0, 0, 40000, 0,0.000000 }, - {2212,2212, 0, 0, 40000, 6,0.000000 }, - {2213,2213, 0, 0, 1080, 1080,0.000000 }, - {2214,2214, 0, 0, 40000, 0,0.000000 }, - {2215,2215, 0, 0, 40000, 73,0.000000 }, - {2216,2216, 0, 0, 40000, 26,0.000000 }, - {2217,2217, 0, 0, 2360, 13,0.000000 }, - {2218,2218, 0, 0, 40000, 0,0.000000 }, - {2219,2219, 0, 0, 3126, 13,0.000000 }, - {2220,2220, 0, 0, 40000, 140,0.000000 }, - {2221,2221, 0, 0, 40000, 26,0.000000 }, - {2222,2222, 0, 0, 40000, 140,0.000000 }, - {2223,2223, 0, 0, 40000, 0,0.000000 }, - {2224,2224, 0, 0, 126, 0,0.000000 }, - {2225,2225, 0, 0, 40000, 6,0.000000 }, - {2226,2226, 0, 0, 40000, 33,0.000000 }, - {2227,2227, 0, 0, 40000, 6,0.000000 }, - {2228,2228, 0, 0, 40000, 6,0.000000 }, - {2229,2229, 0, 0, 40000, 0,0.000000 }, - {2230,2230, 0, 0, 40000, 6,0.000000 }, - {2231,2231, 0, 0, 40000, 20,0.000000 }, - {2232,2232, 0, 0, 40000, 6,0.000000 }, - {2233,2233, 0, 0, 40000, 26,0.000000 }, - {2234,2234, 0, 0, 40000, 266,0.000000 }, - {2235,2235, 0, 0, 40000, 40,0.000000 }, - {2236,2236, 0, 0, 3500, 3500,0.000000 }, - {2237,2237, 0, 0, 860, 20,0.000000 }, - {2238,2238, 0, 0, 513, 513,0.000000 }, - {2239,2239, 0, 0, 973, 973,0.000000 }, - {2240,2240, 0, 0, 1446, 1446,0.000000 }, - {2241,2241, 0, 0, 2280, 2280,0.000000 }, - {2242,2242, 0, 0, 1713, 1713,0.000000 }, - {2243,2243, 0, 0, 200, 200,0.000000 }, - {2244,2244, 0, 0, 40000, 6,0.000000 }, - {2245,2245, 0, 0, 40000, 0,0.000000 }, - {2246,2246, 0, 0, 140, 140,0.000000 }, - {2247,2247, 60, 0, 46, 46,0.000000 }, - {2248,2248, 60, 0, 306, 306,0.000000 }, - {2249,2249, 48, 0, 300, 300,0.000000 }, - {2250,2250, 60, 0, 360, 360,0.000000 }, - {2251,2251, 60, 0, 306, 306,0.000000 }, - {2252,2252, 66, 0, 93, 93,0.000000 }, - {2253,2253, 60, 0, 313, 313,0.000000 }, - {2249,2249, 64, 0, 300, 300,0.000000 }, - {2254,2254, 60, 0, 40, 40,0.000000 }, - {2255,2255, 60, 0, 26, 26,0.000000 }, - {2256,2256, 56, 0, 106, 106,0.000000 }, - {2257,2257, 53, 0, 313, 313,0.000000 }, - {2258,2258, 60, 0, 60, 60,0.000000 }, - {2259,2259, 48, 0, 180, 180,0.000000 }, - {2260,2260, 67, 0, 80, 80,0.000000 }, - {2261,2261, 60, 0, 320, 320,0.000000 }, - {2261,2261, 72, 0, 246, 246,0.000000 }, - {2262,2262, 60, 0, 40, 40,0.000000 }, - {2263,2263, 0, 0, 593, 593,0.000000 }, - {2264,2264, 24, 0, 13, 13,0.000000 }, - {2265,2265, 36, 0, 26, 26,0.000000 }, - { 343, 343, 36, 0, 26, 26,0.000000 }, - { 347, 347, 0, 0, 66, 66,0.000000 }, - { 347, 347, 12, 0, 53, 53,0.000000 }, - {2266,2266, 12, 0, 60, 60,0.000000 }, - {2267,2267, 24, 0, 20, 20,0.000000 }, - {2267,2267, 36, 0, 13, 13,0.000000 }, - {2268,2268, 0, 0, 66, 66,0.000000 }, - {2266,2266, 24, 0, 20, 20,0.000000 }, - {2269,2269, 88, 0, 920, 920,0.000000 }, - {2270,2270, 88, 0, 486, 486,0.000000 }, - {2271,2271, 13, 0, 100, 100,0.000000 }, - { 351, 351, 0, 0, 73, 73,0.000000 }, - {2271,2271, 15, 0, 113, 113,0.000000 }, - {2272,2272, 0, 0, 1226, 1226,0.000000 }, - {2273,2273, 0, 0, 2193, 2193,0.000000 }, - {2274,2274, 0, 0, 866, 866,0.000000 }, - {2275,2275, 0, 0, 886, 886,0.000000 }, - {2276,2276, 0, 0, 1900, 1900,0.000000 }, - {2277,2277, 0, 0, 266, 266,0.000000 }, - {2278,2278, 0, 0, 313, 313,0.000000 }, - {2279,2279, 0, 0, 40000, 1833,0.000000 }, - {2280,2280, 0, 0, 126, 126,0.000000 }, - {2281,2281, 0, 0, 4580, 4580,0.000000 }, - {2282,2282, 0, 0, 253, 253,0.000000 }, - {2283,2283, 0, 0, 120, 120,0.000000 }, - {2284,2284, 0, 0, 40000, 46,0.000000 }, - {2285,2285, 0, 0, 2320, 13,0.000000 }, - {2286,2286, 0, 0, 80, 60,0.000000 }, - {2287,2287, 0, 0, 400, 400,0.000000 }, - {2288,2288, 0, 0, 1953, 1953,0.000000 }, - {2289,2289, 0, 0, 1446, 1446,0.000000 }, - {2290,2290, 0, 0, 360, 360,0.000000 }, - {2291,2291, 0, 0, 40000, 6,0.000000 }, - {2292,2292, 0, 0, 40000, 6,0.000000 }, - {2293,2293, 0, 0, 2026, 2026,0.000000 }, - {2294,2294, 0, 0, 246, 13,0.000000 }, - {2295,2295, 0, 0, 233, 233,0.000000 }, - {2296,2296, 0, 0, 2600, 1333,0.000000 }, - {2297,2297, 79, 0, 20, 20,0.000000 }, - {2297,2297, 72, 0, 20, 20,0.000000 }, - {2298,2298, 72, 0, 13, 13,0.000000 }, - {2298,2298, 79, 0, 13, 13,0.000000 }, - { 554, 554, 60, 0, 160, 160,0.000000 }, - {2299,2299, 72, 0, 253, 253,0.000000 }, - {2300,2300, 84, 0, 106, 106,0.000000 }, - { 555, 555, 66, 0, 20, 20,0.000000 }, - {2301,2302, 35, 0, 20, 20,0.000000 }, - {2303,2304, 52, 0, 20, 20,0.000000 }, - {2305,1548, 48, 0, 66, 66,0.000000 }, - {1595,1595, 58, 0, 33, 33,0.000000 }, - {2305,1548, 60, 0, 73, 73,0.000000 }, - {2306,2307, 47, 0, 606, 606,0.000000 }, - {2306,2307, 43, 0, 313, 313,0.000000 }, - {2306,2307, 49, 0, 706, 706,0.000000 }, - {2306,2307, 51, 0, 840, 840,0.000000 }, - {2306,2307, 54, 0, 820, 820,0.000000 }, - {2306,2307, 57, 0, 780, 780,0.000000 }, - {2306,2307, 72, 0, 713, 713,0.000000 }, - {2306,2307, 60, 0, 786, 786,0.000000 }, - {2306,2307, 76, 0, 720, 720,0.000000 }, - {2306,2307, 84, 0, 720, 720,0.000000 }, - {2306,2307, 36, 0, 193, 193,0.000000 }, - {1560,2308, 65, 0, 113, 113,0.000000 }, - {2309,2310, 84, 0, 40000, 0,0.000000 }, - {1564,1564, 83, 0, 60, 60,0.000000 }, - { 380, 381, 84, 0, 40000, 0,0.000000 }, - {1568,1568, 24, 0, 40, 40,0.000000 }, - {2306,2307, 77, 0, 713, 713,0.000000 }, - {2311,2312, 60, 0, 86, 86,0.000000 }, - {2313,2314, 65, 0, 160, 160,0.000000 }, - {2315,2315, 59, 0, 13, 13,0.000000 }, - {2316,2316, 51, 0, 40, 40,0.000000 }, - {1612,1612, 45, 0, 46, 46,0.000000 }, - {2317,2317, 71, 0, 133, 133,0.000000 }, - {2318,2318, 60, 0, 153, 153,0.000000 }, - {2319,2319, 58, 0, 40, 40,0.000000 }, - {2320,2320, 53, 0, 40, 40,0.000000 }, - { 397, 397, 64, 0, 86, 86,0.000000 }, - {2321,2321, 71, 0, 13, 13,0.000000 }, - {2322,2322, 61, 0, 326, 326,0.000000 }, - {2323,2323, 61, 0, 640, 640,0.000000 }, - {2324, 392, 44, 0, 80, 80,0.000000 }, - {2324, 393, 40, 0, 40, 40,0.000000 }, - {1595,1595, 69, 0, 20, 20,0.000000 }, - {1595,1595, 68, 0, 20, 20,0.000000 }, - {1595,1595, 63, 0, 33, 33,0.000000 }, - {2325,2326, 74, 0, 200, 200,0.000000 }, - {2327,2328, 60, 0, 340, 340,0.000000 }, - {2329,2330, 80, 0, 113, 113,0.000000 }, - {2331,2332, 64, 0, 500, 500,0.000000 }, - { 397, 397, 72, 0, 73, 73,0.000000 }, - {2333,2334, 78, 0, 806, 806,0.000000 }, - {1608,1609, 82, 0, 353, 353,0.000000 }, - {2315,2315, 48, 0, 13, 13,0.000000 }, - {2316,2316, 53, 0, 40, 40,0.000000 }, - {2335,2335, 0, 0, 546, 546,0.000000 }, - {2336,2337, 0, 0, 546, 546,0.000000 }, - {2338,2339, 0, 0, 40000, 86,0.000000 }, - {2340,2340, 0, 0, 1580, 1580,0.000000 }, - {2341,2341, 0, 0, 1153, 1153,0.000000 }, - {2342,2342, 0, 0, 40000, 220,0.000000 }, - {2343,2343, 0, 0, 40000, 240,0.000000 }, - {2344,2345, 0, 0, 380, 380,0.000000 }, - {2346,2346, 0, 0, 40000, 6,0.000000 }, - {2347,2348, 0, 0, 40000, 20,0.000000 }, - {2349,2350, 0, 0, 40000, 6,0.000000 }, - {2351,2352, 0, 0, 40000, 6,0.000000 }, - {2353,2354, 0, 0, 40000, 20,0.000000 }, - {2355,2356, 0, 0, 40000, 213,0.000000 }, - {2357,2357, 14, 0, 26, 26,0.000000 }, - {2358,2358, 35, 0, 40, 40,0.000000 }, - {2357,2357, 19, 0, 26, 26,0.000000 }, - {2359,2359, 43, 0, 86, 86,0.000000 }, - {2360,2360, 41, 0, 60, 60,0.000000 }, - {2360,2360, 43, 0, 53, 53,0.000000 }, - {2360,2360, 45, 0, 60, 60,0.000000 }, - {2360,2360, 47, 0, 53, 53,0.000000 }, - {2361,2362, 0, 0, 1553, 1553,0.000000 }, - {2363,2363, 0, 0, 1213, 1213,0.000000 }, - {2364,2364, 0, 0, 2280, 2280,0.000000 }, - {2365,2365, 0, 0, 966, 966,0.000000 }, - {2366,2366, 0, 0, 500, 500,0.000000 }, - {2367,2367, 0, 0, 326, 326,0.000000 }, - {2368,2368, 0, 0, 1926, 1926,0.000000 }, - {2369,2369, 0, 0, 520, 520,0.000000 }, - {2370,2370, 0, 0, 993, 993,0.000000 }, - {2371,2371, 0, 0, 1740, 1740,0.000000 }, - {2372,2372, 0, 0, 2300, 80,0.000000 }, - {2373,2373, 0, 0, 513, 513,0.000000 }, - {2374,2374, 0, 0, 40, 40,0.000000 }, - {2375,2375, 0, 0, 1226, 1226,0.000000 }, - {2376,2376, 0, 0, 606, 606,0.000000 }, - {2377,2377, 0, 0, 40000, 6,0.000000 }, - {2378,2378, 0, 0, 993, 6,0.000000 }, - {2379,2379, 0, 0, 40000, 153,0.000000 }, - {2380,2380, 0, 0, 40000, 6,0.000000 }, - {2381,2381, 0, 0, 40000, 0,0.000000 }, - {2382,2382, 0, 0, 40000, 6,0.000000 }, - {2383,2383, 0, 0, 40000, 6,0.000000 }, - {2384,2384, 0, 0, 40000, 6,0.000000 }, - {2385,2385, 0, 0, 273, 273,0.000000 }, - {2386,2386, 0, 0, 1580, 1580,0.000000 }, - {2387,2387, 0, 0, 140, 140,0.000000 }, - { 402, 402, 0, 0, 146, 146,0.000000 }, - {2388,2388, 0, 0, 40000, 446,0.000000 }, - {2389,2389, 0, 0, 2006, 2006,0.000000 }, - {2390,2390, 0, 0, 353, 353,0.000000 }, - {2391,2391, 0, 0, 233, 233,0.000000 }, - {2392,2392, 0, 0, 226, 226,0.000000 }, - {2393,2393, 0, 0, 853, 853,0.000000 }, - {2394,2394, 0, 0, 100, 100,0.000000 }, - {2395,2395, 0, 0, 40000, 40,0.000000 }, - {2396,2397, 0, 0, 633, 20,0.000000 }, - {2398,2398, 0, 0, 40, 40,0.000000 }, - {2399,2400, 0, 0, 493, 493,0.000000 }, - {2401,2401, 0, 0, 40000, 86,0.000000 }, - {2402,2402, 0, 0, 40000, 0,0.000000 }, - {2403,2404, 0, 0, 40000, 66,0.000000 }, - {2405,2406, 0, 0, 186, 46,0.000000 }, - {2407,2408, 0, 0, 40000, 6,0.000000 }, - {2409,2409, 0, 0, 1153, 1153,0.000000 }, - {2410,2410, 0, 0, 40000, 0,0.000000 }, - {2411,2411, 0, 0, 86, 86,0.000000 }, - {2412,2413, 0, 0, 40000, 73,0.000000 }, - {2414,2414, 0, 0, 40000, 40,0.000000 }, - {2415,2416, 0, 0, 40000, 286,0.000000 }, - {2417,2418, 0, 0, 40000, 20,0.000000 }, - {2419,2420, 0, 0, 600, 600,0.000000 }, - {2421,2422, 0, 0, 253, 253,0.000000 }, - {2423,2424, 0, 0, 466, 466,0.000000 }, - {2425,2426, 0, 0, 40000, 6,0.000000 }, - {2427,2427, 33, 0, 53, 53,0.000000 }, - {2428,2429, 38, 0, 46, 46,0.000000 }, - {2430,2430, 38, 0, 13, 13,0.000000 }, - {2431,2431, 38, 0, 86, 86,0.000000 }, - {2432,2432, 40, 0, 6, 6,0.000000 }, - {2433,2434, 41, 0, 60, 60,0.000000 }, - {2435,2435, 0, 0, 20, 20,0.000000 }, - {2435,2435, 41, 0, 26, 26,0.000000 }, - {2360,2360, 48, 0, 53, 53,0.000000 }, - {2436,2436, 17, 0, 446, 446,0.000000 }, - {2360,2360, 50, 0, 46, 46,0.000000 }, - {2435,2435, 45, 0, 20, 20,0.000000 }, - {2437,2437,254, 0, 26, 26,0.000000 }, - {2438,2438, 60, 0, 80, 80,0.000000 }, - {2439,2439, 56, 0, 80, 80,0.000000 }, - {2440,2440, 60, 0, 40, 40,0.000000 }, - {2440,2440, 55, 0, 40, 40,0.000000 }, - {2441,2441, 63, 0, 86, 86,0.000000 }, - {2442,2442, 57, 0, 40, 40,0.000000 }, - {2443,2443, 0, 0, 40000, 106,0.000000 }, - {2444,2444, 0, 0, 246, 246,0.000000 }, - {2445,2445, 0, 0, 3133, 13,0.000000 }, - {2446,2446, 0, 0, 40000, 153,0.000000 }, - {2447,2447, 0, 0, 40000, 480,0.000000 }, - {2448,2448, 0, 0, 40000, 73,0.000000 }, - {2449,2449, 0, 0, 40000, 526,0.000000 }, - {2450,2450, 0, 0, 40000, 146,0.000000 }, - {2451,2451, 0, 0, 4520, 4520,0.000000 }, - {2452,2452, 0, 0, 280, 280,0.000000 }, - { 752, 752, 55, 0, 46, 46,0.000000 }, - {2453,2453, 0, 0, 646, 646,0.000000 }, - {2454,2454, 0, 0, 600, 600,0.000000 }, - {2455,2455, 0, 0, 86, 86,0.000000 }, - {2456,2456, 0, 0, 386, 386,0.000000 }, - {2457,2457, 0, 0, 40000, 0,0.000000 }, - {2458,2458, 0, 0, 1340, 1340,0.000000 }, - {2459,2459, 0, 0, 786, 786,0.000000 }, - {2460,2460, 0, 0, 680, 680,0.000000 }, - {2461,2461, 0, 0, 2113, 2113,0.000000 }, - {2462,2462, 0, 0, 3193, 13,0.000000 }, - {2463,2463, 0, 0, 726, 726,0.000000 }, - { 884, 884, 0, 0, 46, 46,0.000000 }, - { 884, 884, 28, 0, 100, 100,0.000000 }, - {2464,2464, 29, 0, 66, 66,0.000000 }, - { 886, 886, 31, 0, 20, 20,0.000000 }, - { 360, 360, 32, 0, 46, 46,0.000000 }, - { 361, 361, 33, 0, 100, 100,0.000000 }, - {2453,2453, 34, 0, 760, 760,0.000000 }, - { 888, 888, 29, 0, 46, 46,0.000000 }, - { 886, 886, 55, 0, 13, 13,0.000000 }, - { 890, 890, 48, 0, 73, 73,0.000000 }, - { 884, 884, 58, 0, 40, 40,0.000000 }, - {2465,2465, 45, 0, 46, 46,0.000000 }, - {2465,2465, 43, 0, 46, 46,0.000000 }, - {2466,2466, 73, 0, 520, 520,0.000000 }, - {2467,2467, 72, 0, 266, 266,0.000000 }, - {2468,2468, 76, 0, 160, 160,0.000000 }, - {2467,2467, 84, 0, 273, 273,0.000000 }, - {2468,2468, 36, 0, 166, 166,0.000000 }, - {2469,2469, 65, 0, 86, 86,0.000000 }, - {2470,2470, 83, 0, 73, 73,0.000000 }, - {2471,2471, 50, 0, 300, 300,0.000000 }, - {2468,2468, 77, 0, 133, 133,0.000000 }, - { 897, 897, 55, 0, 33, 33,0.000000 }, - {2472,2472, 60, 0, 46, 46,0.000000 }, - { 897, 897, 50, 0, 33, 33,0.000000 }, - {2473,2473, 42, 0, 206, 206,0.000000 }, - {2473,2473, 46, 0, 166, 166,0.000000 }, - {2474,2474, 71, 0, 133, 133,0.000000 }, - {2474,2474, 60, 0, 160, 160,0.000000 }, - {2455,2455, 58, 0, 66, 66,0.000000 }, - {2455,2455, 53, 0, 86, 86,0.000000 }, - {2475,2475, 91, 0, 40, 40,0.000000 }, - {2476,2476, 61, 0, 140, 140,0.000000 }, - {2477,2477, 61, 0, 786, 786,0.000000 }, - {2478,2478, 44, 0, 33, 33,0.000000 }, - {2479,2479, 40, 0, 840, 840,0.000000 }, - {2480,2480, 69, 0, 40, 40,0.000000 }, - { 361, 361, 68, 0, 40, 40,0.000000 }, - { 361, 361, 63, 0, 60, 60,0.000000 }, - {2481,2481, 74, 0, 73, 73,0.000000 }, - {2482,2482, 60, 0, 73, 73,0.000000 }, - { 908, 908, 80, 0, 33, 33,0.000000 }, - {2483,2483, 64, 0, 306, 306,0.000000 }, - {2483,2483, 73, 0, 260, 260,0.000000 }, - {2483,2483, 70, 0, 260, 260,0.000000 }, - { 886, 886, 68, 0, 6, 6,0.000000 }, - { 886, 886, 48, 0, 13, 13,0.000000 }, - {2484,2484, 0, 0, 440, 440,0.000000 }, - {2485,2485, 0, 0, 253, 253,0.000000 }, - {2486,2486, 0, 0, 306, 306,0.000000 }, - {2487,2487, 0, 0, 1213, 1213,0.000000 }, - {2488,2488, 0, 0, 626, 626,0.000000 }, - {2489,2489, 0, 0, 40000, 206,0.000000 }, - {2490,2490, 0, 0, 40000, 100,0.000000 }, - {2491,2491, 0, 0, 40000, 13,0.000000 }, - {2492,2492, 0, 0, 2273, 2273,0.000000 }, - {2493,2493, 0, 0, 1740, 1740,0.000000 }, - {2494,2494, 0, 0, 1953, 1953,0.000000 }, - {2495,2495, 0, 0, 1740, 1740,0.000000 }, - {2496,2496, 0, 0, 386, 386,0.000000 }, - {2497,2497, 0, 0, 233, 233,0.000000 }, - {2498,2498, 0, 0, 40000, 106,0.000000 }, - {2499,2499, 0, 0, 40000, 13,0.000000 }, - {2500,2500, 0, 0, 40000, 0,0.000000 }, - {2501,2501, 0, 0, 40000, 186,0.000000 }, - {2502,2502, 0, 0, 66, 66,0.000000 }, - {2503,2503, 0, 0, 46, 46,0.000000 }, - {2504,2504, 0, 0, 40000, 186,0.000000 }, - {2505,2505, 0, 0, 1106, 1106,0.000000 }, - {2506,2506, 0, 0, 40000, 186,0.000000 }, - {2507,2507, 0, 0, 40000, 100,0.000000 }, - {2508,2508, 0, 0, 40000, 206,0.000000 }, - {2509,2509, 0, 0, 40000, 60,0.000000 }, - {2510,2510, 0, 0, 40000, 106,0.000000 }, - {2511,2511, 0, 0, 60, 60,0.000000 }, - {2512,2512, 0, 0, 40, 40,0.000000 }, - {2513,2513, 0, 0, 1833, 26,0.000000 }, - {2514,2514, 0, 0, 806, 806,0.000000 }, - {2515,2515, 0, 0, 1106, 1106,0.000000 }, - {2516,2516, 0, 0, 40000, 6,0.000000 }, - {2517,2517, 0, 0, 40000, 180,0.000000 }, - {2518,2518, 0, 0, 40000, 340,0.000000 }, - {2519,2519, 0, 0, 1873, 6,0.000000 }, - {2520,2520, 0, 0, 2586, 2586,0.000000 }, - {2521,2521, 0, 0, 1740, 1740,0.000000 }, - {2522,2522, 0, 0, 3493, 13,0.000000 }, - {2523,2523, 0, 0, 40000, 266,0.000000 }, - {2524,2524, 0, 0, 6160, 33,0.000000 }, - {2525,2525, 0, 0, 40000, 46,0.000000 }, - {2526,2526, 0, 0, 1140, 1140,0.000000 }, - { 346, 346, 30, 0, 46, 46,0.000000 }, - { 346, 346, 31, 0, 33, 33,0.000000 }, - { 346, 346, 32, 0, 40, 40,0.000000 }, - { 346, 346, 33, 0, 46, 46,0.000000 }, - { 346, 346, 34, 0, 53, 53,0.000000 }, - { 346, 346, 35, 0, 33, 33,0.000000 }, - { 346, 346, 37, 0, 146, 146,0.000000 }, - { 346, 346, 39, 0, 186, 186,0.000000 }, - { 346, 346, 41, 0, 206, 206,0.000000 }, - { 346, 346, 43, 0, 133, 133,0.000000 }, - { 346, 346, 45, 0, 126, 126,0.000000 }, - { 346, 346, 47, 0, 153, 153,0.000000 }, - { 346, 346, 48, 0, 153, 153,0.000000 }, - { 346, 346, 49, 0, 153, 153,0.000000 }, - { 512, 512, 84, 0, 73, 73,0.000000 }, - {2206,2206, 84, 0, 140, 140,0.000000 }, - {2527,2527, 55, 0, 13, 13,0.000000 }, - {2528,2528, 36, 0, 20, 20,0.000000 }, - {2529,2529, 38, 0, 66, 66,0.000000 }, - {2530,2530, 60, 0, 86, 86,0.000000 }, - {2531,2531, 38, 0, 60, 60,0.000000 }, - {2532,2532, 17, 0, 2233, 2233,0.000000 }, - {2532,2532, 18, 0, 2266, 2266,0.000000 }, - {2532,2532, 19, 0, 2280, 2280,0.000000 }, - {2532,2532, 20, 0, 46, 46,0.000000 }, - {2532,2532, 21, 0, 46, 46,0.000000 }, - {2532,2532, 22, 0, 40, 40,0.000000 }, - {2532,2532, 23, 0, 53, 53,0.000000 }, - {2532,2532, 24, 0, 100, 100,0.000000 }, - {2532,2532, 25, 0, 46, 46,0.000000 }, - {2532,2532, 26, 0, 60, 60,0.000000 }, - {2532,2532, 27, 0, 40, 40,0.000000 }, - {2532,2532, 28, 0, 53, 53,0.000000 }, - {2532,2532, 29, 0, 126, 126,0.000000 }, - {2533,2533, 84, 0, 133, 133,0.000000 }, - {2534,2534, 48, 0, 86, 86,0.000000 }, - {2535,2535, 65, 0, 486, 486,0.000000 }, - {2536,2536, 65, 0, 526, 526,0.000000 }, - {2537,2537, 55, 0, 66, 66,0.000000 }, - {2537,2537, 41, 0, 60, 60,0.000000 }, - { 346, 346, 63, 0, 106, 106,0.000000 }, - { 346, 346, 55, 0, 106, 106,0.000000 }, - {2538,2538, 55, 0, 1200, 1200,0.000000 }, - {2538,2538, 53, 0, 1206, 1206,0.000000 }, - {2534,2534, 50, 0, 86, 86,0.000000 }, - { 506, 506, 84, 0, 133, 133,0.000000 }, - { 506, 506, 74, 0, 133, 133,0.000000 }, - { 504, 504, 84, 0, 473, 473,0.000000 }, - { 504, 504, 74, 0, 486, 486,0.000000 }, - {2539,2539, 84, 0, 133, 133,0.000000 }, - {2540,2540, 74, 0, 20, 20,0.000000 }, - {1911,1911, 48, 0, 46, 46,0.000000 }, - {1911,1911, 36, 0, 20, 20,0.000000 }, - {2541,2541, 74, 0, 133, 133,0.000000 }, - {2542,2542, 0, 0, 613, 613,0.000000 }, - {2543,2543, 0, 0, 40000, 480,0.000000 }, - {2544,2544, 0, 0, 1133, 1133,0.000000 }, - {2545,2545, 0, 0, 1200, 1200,0.000000 }, - {2546,2547, 0, 0, 1313, 1313,0.000000 }, - {2548,2549, 0, 0, 40000, 6,0.000000 }, - {2550,2550, 0, 0, 1740, 1740,0.000000 }, - {2551,2552, 0, 0, 860, 860,0.000000 }, - {2553,2553, 0, 0, 40000, 0,0.000000 }, - {2554,2554, 0, 0, 2300, 2300,0.000000 }, - {2555,2556, 0, 0, 40000, 0,0.000000 }, - {2557,2557, 0, 0, 506, 13,0.000000 }, - {2558,1467, 0, 0, 40000, 6,0.000000 }, - {2559,2560, 0, 0, 40000, 0,0.000000 }, - {2561,2561, 0, 0, 40000, 106,0.000000 }, - {2562,2562, 0, 0, 1013, 1013,0.000000 }, - {2563,2564, 0, 0, 1020, 1020,0.000000 }, - {2565,2565, 0, 0, 1746, 1746,0.000000 }, - {2566,2567, 0, 0, 1446, 1446,0.000000 }, - {2568,2568, 0, 0, 826, 826,0.000000 }, - {2569,2569, 0, 0, 2293, 2293,0.000000 }, - {2570,2570, 0, 0, 2386, 2386,0.000000 }, - {2571,2572, 0, 0, 40000, 46,0.000000 }, - {2573,2574, 0, 0, 40000, 26,0.000000 }, - {2575,2575, 0, 0, 40000, 126,0.000000 }, - { 229,2576, 0, 0, 1893, 13,0.000000 }, - {2577,2577, 0, 0, 1046, 1046,0.000000 }, - { 239,2578, 0, 0, 40000, 53,0.000000 }, - {2579,2579, 0, 0, 40000, 13,0.000000 }, - {2580,2580, 0, 0, 40000, 66,0.000000 }, - {2581,2582, 0, 0, 3466, 3466,0.000000 }, - {2583,2584, 0, 0, 233, 233,0.000000 }, - {2585,2586, 0, 0, 40000, 0,0.000000 }, - {2587,2588, 0, 0, 40000, 0,0.000000 }, - {2589,2589, 0, 0, 40000, 6,0.000000 }, - {2590,2590, 0, 0, 40000, 6,0.000000 }, - {2591,2592, 0, 0, 40000, 0,0.000000 }, - {2593,2594, 0, 0, 680, 0,0.000000 }, - {2595,2595, 0, 0, 40000, 0,0.000000 }, - {2596,2597, 0, 0, 40000, 6,0.000000 }, - {2598,2599, 0, 0, 40000, 0,0.000000 }, - {2600,2601, 0, 0, 40000, 13,0.000000 }, - {2602,2602, 0, 0, 5093, 5093,0.000000 }, - {2603,2603, 0, 0, 40000, 6,0.000000 }, - {2604,2604, 0, 0, 40000, 40,0.000000 }, - {2605,2606, 0, 0, 40000, 0,0.000000 }, - {2607,2607, 0, 0, 40000, 0,0.000000 }, - {2608,2609, 0, 0, 40000, 6,0.000000 }, - {2610,2610, 0, 0, 40000, 20,0.000000 }, - {2611,2611, 0, 0, 40000, 6,0.000000 }, - {2612,2612, 0, 0, 2253, 2253,0.000000 }, - {2613,2613, 0, 0, 973, 973,0.000000 }, - {2614,2615, 0, 0, 40000, 6,0.000000 }, - {2616,2617, 0, 0, 40000, 6,0.000000 }, - {2618,2619, 0, 0, 353, 353,0.000000 }, - {2620,2621, 0, 0, 40000, 500,0.000000 }, - {2622,2623, 0, 0, 40000, 26,0.000000 }, - {2624,2625, 0, 0, 40000, 53,0.000000 }, - {2626,2627, 0, 0, 4026, 13,0.000000 }, - {2628,2629, 0, 0, 3400, 13,0.000000 }, - {1516,2630, 0, 0, 226, 226,0.000000 }, - {2631,2632, 0, 0, 40000, 193,0.000000 }, - {2633,2633, 0, 0, 2380, 2380,0.000000 }, - {2634,2635, 0, 0, 40000, 373,0.000000 }, - {2636,2636, 0, 0, 40000, 133,0.000000 }, - {2637,2637, 0, 0, 280, 280,0.000000 }, - {2638,2639, 0, 0, 273, 273,0.000000 }, - {2640,2641, 0, 0, 3333, 3333,0.000000 }, - {2642,2642, 0, 0, 40000, 266,0.000000 }, - {2643,2644, 0, 0, 166, 166,0.000000 }, - {2645,2645, 0, 0, 40000, 6,0.000000 }, - {2646,2647, 0, 0, 40000, 0,0.000000 }, - {2648,2648, 0, 0, 586, 586,0.000000 }, - {2649,2649, 0, 0, 1660, 86,0.000000 }, - {2650,2651, 0, 0, 440, 440,0.000000 }, - {2652,2652, 0, 0, 40000, 113,0.000000 }, - {2653,2654, 0, 0, 40000, 6,0.000000 }, - {2655,2656, 0, 0, 1766, 1766,0.000000 }, - {2657,2657, 0, 0, 40000, 0,0.000000 }, - {2658,2658, 35, 0, 20, 20,0.000000 }, - {2659,2659, 35, 0, 26, 26,0.000000 }, - {2660,2660, 52, 0, 20, 20,0.000000 }, - {2661,2661, 60, 0, 80, 80,0.000000 }, - {2662,2662, 58, 0, 20, 20,0.000000 }, - {2663,2663, 60, 0, 113, 113,0.000000 }, - {2664,2664, 50, 0, 433, 433,0.000000 }, - {2665,2665, 43, 0, 40, 40,0.000000 }, - {2664,2664, 55, 0, 513, 513,0.000000 }, - {1553,1553, 43, 0, 26, 26,0.000000 }, - {2666,2666, 50, 0, 173, 173,0.000000 }, - {2667,2667, 43, 0, 173, 173,0.000000 }, - {2666,2666, 53, 0, 40, 40,0.000000 }, - {2666,2666, 57, 0, 186, 186,0.000000 }, - {2668,2668, 72, 0, 260, 260,0.000000 }, - {2666,2666, 60, 0, 220, 220,0.000000 }, - { 373, 373, 76, 0, 260, 260,0.000000 }, - {2669,2669, 84, 0, 213, 213,0.000000 }, - {2670,2670, 42, 0, 406, 406,0.000000 }, - {2671,2671, 65, 0, 86, 86,0.000000 }, - {2672,2672, 84, 0, 113, 113,0.000000 }, - {2673,2673, 84, 0, 426, 426,0.000000 }, - {2674,2674, 24, 0, 46, 46,0.000000 }, - { 383, 383, 77, 0, 246, 246,0.000000 }, - {2675,2675, 58, 0, 153, 153,0.000000 }, - {2676,2676, 53, 0, 153, 153,0.000000 }, - {2677,2677, 64, 0, 73, 73,0.000000 }, - {2678,2678, 71, 0, 26, 26,0.000000 }, - {2679,2679, 44, 0, 606, 606,0.000000 }, - {2680,2680, 40, 0, 366, 366,0.000000 }, - {2681,2681, 69, 0, 20, 20,0.000000 }, - {2682,2682, 60, 0, 360, 360,0.000000 }, - {2683,2683, 80, 0, 60, 60,0.000000 }, - {2684,2684, 64, 0, 873, 873,0.000000 }, - {2685,2685, 72, 0, 33, 33,0.000000 }, - {2686,2686, 70, 0, 273, 273,0.000000 }, - {2687,2687, 48, 0, 40, 40,0.000000 }, - {2688,2688, 53, 0, 213, 213,0.000000 }, - {2689,2690, 0, 0, 40000, 140,0.000000 }, - {2691,2692, 0, 0, 626, 626,0.000000 }, - {2693,2694, 0, 0, 40000, 0,0.000000 }, - {2695,2696, 0, 0, 2213, 2213,0.000000 }, - {2697,2698, 0, 0, 4140, 0,0.000000 }, - { 192,2699, 0, 0, 40000, 6,0.000000 }, - {2700,2701, 0, 0, 153, 153,0.000000 }, - {2702,2703, 0, 0, 253, 253,0.000000 }, - {2704,2705, 0, 0, 40000, 0,0.000000 }, - {2706,2707, 0, 0, 40000, 6,0.000000 }, - {2708,2709, 0, 0, 40000, 6,0.000000 }, - {2710,2711, 0, 0, 440, 440,0.000000 }, - {2712,1473, 0, 0, 213, 213,0.000000 }, - {2713,2714, 0, 0, 120, 120,0.000000 }, - {2715,2716, 0, 0, 140, 140,0.000000 }, - {1478,2717, 0, 0, 40000, 113,0.000000 }, - {2718,2719, 0, 0, 40000, 6,0.000000 }, - { 286,2720, 0, 0, 40000, 20,0.000000 }, - {2721,2722, 0, 0, 40000, 13,0.000000 }, - {2723,2724, 0, 0, 40000, 0,0.000000 }, - {2725,2726, 0, 0, 526, 526,0.000000 }, - {2727,2724, 0, 0, 40000, 0,0.000000 }, - {1514,2728, 0, 0, 40000, 53,0.000000 }, - {2729,2730, 0, 0, 186, 186,0.000000 }, - {2731,2732, 0, 0, 226, 226,0.000000 }, - {2733,2734, 0, 0, 266, 266,0.000000 }, - {2735,2736, 0, 0, 80, 80,0.000000 }, - {2737,2738, 0, 0, 40000, 0,0.000000 }, - {2739,2740, 0, 0, 260, 260,0.000000 }, - {2741,2742, 0, 0, 286, 286,0.000000 }, - {2743,2744, 0, 0, 193, 193,0.000000 }, - {2745,2746, 0, 0, 40000, 0,0.000000 }, - {2747,2747, 35, 0, 20, 20,0.000000 }, - {2748,2748, 60, 0, 153, 153,0.000000 }, - {2749,2749, 43, 0, 20, 20,0.000000 }, - {2750,2750, 0, 0, 626, 626,0.000000 }, - {2751,2752, 0, 0, 1553, 1553,0.000000 }, - {2753,2754, 0, 0, 1386, 1386,0.000000 }, - {2755,2756, 0, 0, 2026, 2026,0.000000 }, - {2757,2758, 0, 0, 1020, 1020,0.000000 }, - {2759,2760, 0, 0, 2486, 2486,0.000000 }, - {2761,2762, 0, 0, 2880, 2880,0.000000 }, - {2763,2764, 0, 0, 2346, 2346,0.000000 }, - {2765,2766, 0, 0, 40000, 0,0.000000 }, - {2767,2768, 0, 0, 40000, 100,0.000000 }, - {2769,2770, 0, 0, 40000, 13,0.000000 }, - {2771,2772, 0, 0, 40000, 6,0.000000 }, - {2773,2774, 0, 0, 40000, 0,0.000000 }, - {2775,2776, 0, 0, 40000, 13,0.000000 }, - {2777,2778, 0, 0, 40000, 0,0.000000 }, - {2779,2780, 0, 0, 40000, 6,0.000000 }, - {2781,2782, 0, 0, 40000, 6,0.000000 }, - {2783,2784, 0, 0, 913, 913,0.000000 }, - {2785,2786, 0, 0, 1653, 1653,0.000000 }, - {2787,2788, 0, 0, 40000, 153,0.000000 }, - {2789,2790, 0, 0, 1273, 1273,0.000000 }, - {2791,2792, 0, 0, 1166, 1166,0.000000 }, - {2793,2794, 0, 0, 386, 386,0.000000 }, - {2795,2796, 0, 0, 40000, 1993,0.000000 }, - {2795,2797, 0, 0, 2526, 1333,0.000000 }, - {2798,2799, 0, 0, 166, 6,0.000000 }, - {2800,2801, 0, 0, 13080, 213,0.000000 }, - {2802,2803, 0, 0, 40000, 6,0.000000 }, - {2804,2805, 0, 0, 40000, 6,0.000000 }, - {2806,2807, 0, 0, 493, 493,0.000000 }, - {2808,2809, 0, 0, 126, 6,0.000000 }, - {2810,2811, 0, 0, 80, 80,0.000000 }, - {2812,2813, 0, 0, 380, 380,0.000000 }, - {2814,2815, 0, 0, 2506, 2506,0.000000 }, - {2816,2817, 0, 0, 2186, 2186,0.000000 }, - {2818,2819, 0, 0, 2520, 2520,0.000000 }, - {2820,2821, 0, 0, 440, 440,0.000000 }, - {2822,2823, 0, 0, 106, 106,0.000000 }, - {2824,2825, 0, 0, 1933, 1933,0.000000 }, - {2826,2827, 0, 0, 40000, 6,0.000000 }, - {2828,2829, 0, 0, 1933, 1933,0.000000 }, - {2830,2831, 0, 0, 546, 546,0.000000 }, - {2832,2833, 0, 0, 973, 973,0.000000 }, - {2834,2835, 0, 0, 586, 26,0.000000 }, - {2836,2837, 0, 0, 786, 786,0.000000 }, - {2838,2839, 0, 0, 1920, 1920,0.000000 }, - {2840,2841, 0, 0, 333, 333,0.000000 }, - {2842,2843, 0, 0, 1120, 1120,0.000000 }, - {2844,2845, 0, 0, 40000, 153,0.000000 }, - {2846,2847, 0, 0, 40000, 153,0.000000 }, - {2848,2849, 0, 0, 40000, 153,0.000000 }, - {2850,2851, 0, 0, 40000, 213,0.000000 }, - {2852,2853, 0, 0, 40000, 240,0.000000 }, - {2854,2855, 0, 0, 40000, 93,0.000000 }, - {2856,2856, 0, 0, 333, 333,0.000000 }, - {2857,2857, 0, 0, 333, 333,0.000000 }, - {2858,2859, 0, 0, 866, 866,0.000000 }, - {2860,2861, 0, 0, 40000, 180,0.000000 }, - {2862,2863, 0, 0, 866, 866,0.000000 }, - {2864,2865, 0, 0, 40000, 6,0.000000 }, - {2866,2867, 0, 0, 946, 946,0.000000 }, - {2868,2869, 0, 0, 906, 906,0.000000 }, - {2870,2871, 0, 0, 846, 846,0.000000 }, - {2872,2873, 0, 0, 160, 160,0.000000 }, - {2874,2875, 0, 0, 586, 6,0.000000 }, - {2876,2877, 0, 0, 160, 160,0.000000 }, - {2878,2879, 0, 0, 760, 760,0.000000 }, - {2880,2881, 0, 0, 1193, 1193,0.000000 }, - {2882,2883, 0, 0, 493, 493,0.000000 }, - {2884,2885, 0, 0, 893, 893,0.000000 }, - {2886,2887, 0, 0, 40000, 0,0.000000 }, - {2888,2888, 0, 0, 4413, 4413,0.000000 }, - {2889,2889, 0, 0, 4193, 4193,0.000000 }, - {2890,2890, 0, 0, 3946, 3946,0.000000 }, - {2891,2892, 0, 0, 40000, 26,0.000000 }, - {2893,2893, 0, 0, 60, 60,0.000000 }, - {2894,2894, 0, 0, 40, 40,0.000000 }, - {2895,2895, 0, 0, 1773, 1773,0.000000 }, - {2896,2897, 0, 0, 40000, 6,0.000000 }, - {2898,2899, 0, 0, 1073, 6,0.000000 }, - {2353,2900, 0, 0, 4800, 4800,0.000000 }, - {2901,2901, 0, 0, 126, 126,0.000000 }, - {2902,2903, 0, 0, 40000, 20,0.000000 }, - {2904,2905, 0, 0, 40000, 20,0.000000 }, - {2906,2907, 0, 0, 40000, 6,0.000000 }, - {2908,2909, 0, 0, 4546, 4546,0.000000 }, - {2910,2911, 0, 0, 40000, 6,0.000000 }, - {2912,2912, 0, 0, 913, 913,0.000000 }, - {2913,2914, 0, 0, 486, 486,0.000000 }, - {2915,2916, 0, 0, 1740, 1740,0.000000 }, - {2917,2918, 0, 0, 1726, 1726,0.000000 }, - {2919,2920, 0, 0, 1740, 1740,0.000000 }, - {2921,2922, 0, 0, 1420, 1420,0.000000 }, - {2923,2924, 0, 0, 546, 546,0.000000 }, - {2925,2926, 0, 0, 513, 513,0.000000 }, - {2927,2928, 0, 0, 226, 226,0.000000 }, - {2929,2929, 0, 0, 40000, 73,0.000000 }, - {2930,2931, 0, 0, 40000, 33,0.000000 }, - {2932,2933, 0, 0, 40000, 6,0.000000 }, - {2934,2935, 0, 0, 40000, 20,0.000000 }, - {2936,2937, 0, 0, 40000, 13,0.000000 }, - {2938,2939, 0, 0, 40000, 106,0.000000 }, - {2940,2940, 0, 0, 40, 40,0.000000 }, - {2941,2941, 0, 0, 40000, 86,0.000000 }, - {2942,2943, 0, 0, 293, 293,0.000000 }, - {2944,2944, 0, 0, 53, 53,0.000000 }, - {2945,2945, 0, 0, 260, 260,0.000000 }, - {2946,2947, 0, 0, 1026, 1026,0.000000 }, - {2948,2948, 0, 0, 40000, 120,0.000000 }, - {2949,2949, 0, 0, 280, 280,0.000000 }, - {2950,2951, 0, 0, 3926, 3926,0.000000 }, - {2952,2953, 0, 0, 6373, 206,0.000000 }, - {2954,2954, 60, 0, 40000, 0,0.000000 }, - {2955,2956, 0, 0, 40000, 153,0.000000 }, - {2957,2958, 0, 0, 40000, 6,0.000000 }, - {2959,2960, 0, 0, 40000, 26,0.000000 }, - {2961,2962, 0, 0, 700, 140,0.000000 }, - {2963,2963, 0, 0, 506, 506,0.000000 }, - {2964,2964, 0, 0, 40000, 680,0.000000 }, - {2436,2436, 49, 0, 593, 593,0.000000 }, - {2357,2357, 61, 0, 26, 26,0.000000 }, - {2357,2357, 56, 0, 26, 26,0.000000 }, - {2357,2357, 58, 0, 26, 26,0.000000 }, - {2357,2357, 49, 0, 33, 33,0.000000 }, - {2357,2357, 44, 0, 26, 26,0.000000 }, - {2965,2965, 0, 0, 40000, 186,0.000000 }, - {2966,2966, 0, 0, 186, 186,0.000000 }, - {2967,2967, 0, 0, 1793, 1793,0.000000 }, - {2968,2968, 0, 0, 40000, 53,0.000000 }, - {2969,2969, 0, 0, 80, 80,0.000000 }, - {2970,2970, 84, 0, 40, 40,0.000000 }, - {2971,2971, 72, 0, 140, 140,0.000000 }, - {2972,2972, 0, 0, 2080, 2080,0.000000 }, - {2973,2973, 0, 0, 40000, 66,0.000000 }, - {2974,2974, 0, 0, 40000, 2100,0.000000 }, - {2975,2975, 0, 0, 1766, 1766,0.000000 }, - {2976,2976, 0, 0, 120, 120,0.000000 }, - {2977,2977, 0, 0, 40000, 0,0.000000 }, - {2978,2978, 0, 0, 40000, 66,0.000000 }, - {2979,2979, 0, 0, 40000, 73,0.000000 }, - {2980,2980, 0, 0, 40000, 126,0.000000 }, - {2981,2981, 0, 0, 40000, 506,0.000000 }, - {2982,2982, 0, 0, 40000, 373,0.000000 }, - {2983,2983, 0, 0, 920, 920,0.000000 }, - {2984,2984, 0, 0, 1106, 1106,0.000000 }, - {2985,2985, 0, 0, 40000, 0,0.000000 }, - {2986,2986, 0, 0, 40000, 0,0.000000 }, - {2987,2987, 0, 0, 40000, 0,0.000000 }, - {2988,2988, 0, 0, 40000, 140,0.000000 }, - {2989,2989, 0, 0, 726, 726,0.000000 }, - {2990,2990, 0, 0, 573, 573,0.000000 }, - {2991,2991, 0, 0, 40000, 146,0.000000 }, - {2992,2992, 0, 0, 40000, 66,0.000000 }, - {2993,2993, 0, 0, 146, 146,0.000000 }, - {2994,2994, 0, 0, 1380, 1380,0.000000 }, - {2995,2995, 0, 0, 40000, 113,0.000000 }, - {2996,2996, 0, 0, 1140, 1140,0.000000 }, - {2997,2997, 0, 0, 1180, 1180,0.000000 }, - {2998,2998, 0, 0, 40000, 0,0.000000 }, - {2999,2999, 0, 0, 40000, 13,0.000000 }, - {3000,3000, 0, 0, 193, 193,0.000000 }, - {3001,3001, 0, 0, 40000, 0,0.000000 }, - {3002,3002, 0, 0, 40000, 433,0.000000 }, - {3003,3003, 0, 0, 1206, 1206,0.000000 }, - {3004,3004, 0, 0, 40000, 480,0.000000 }, - {3005,3005, 0, 0, 40000, 0,0.000000 }, - {3006,3006, 0, 0, 126, 126,0.000000 }, - {3007,3007, 0, 0, 333, 333,0.000000 }, - { 350, 350, 0, 0, 66, 66,0.000000 }, - {3008,3008, 0, 0, 46, 46,0.000000 }, - {3009,3009, 0, 0, 26, 26,0.000000 }, - {3010,3010, 0, 0, 320, 320,0.000000 }, - {3011,3011, 0, 0, 2380, 2380,0.000000 }, - {3012,3012, 0, 0, 180, 180,0.000000 }, - {3013,3013, 0, 0, 260, 260,0.000000 }, - {3014,3014, 0, 0, 40000, 6,0.000000 }, - {3015,3015, 0, 0, 40000, 146,0.000000 }, - { 350, 350, 36, 0, 86, 86,0.000000 }, - { 369, 369, 37, 0, 33, 33,0.000000 }, - {3008,3008, 38, 0, 53, 53,0.000000 }, - { 369, 369, 24, 0, 33, 33,0.000000 }, - {3008,3008, 32, 0, 60, 60,0.000000 }, - { 369, 369, 48, 0, 33, 33,0.000000 }, - {3009,3009, 42, 0, 33, 33,0.000000 }, - { 369, 369, 50, 0, 100, 100,0.000000 }, - { 369, 369, 52, 0, 66, 66,0.000000 }, - { 369, 369, 54, 0, 93, 93,0.000000 }, - { 369, 369, 55, 0, 86, 86,0.000000 }, - { 369, 369, 57, 0, 100, 100,0.000000 }, - {3010,3010, 51, 0, 333, 333,0.000000 }, - { 144, 144, 61, 0, 40, 40,0.000000 }, - {3016,3016, 0, 0, 106, 106,0.000000 }, - {3016,3016, 63, 0, 86, 86,0.000000 }, - {3016,3016, 64, 0, 86, 86,0.000000 }, - {3017,3017, 40, 0, 60, 60,0.000000 }, - {3017,3017, 70, 0, 40, 40,0.000000 }, - {3018,3018, 0, 0, 40000, 6,0.000000 }, - {3019,3019, 0, 0, 40000, 0,0.000000 }, - {3020,3020, 0, 0, 40000, 6,0.000000 }, - {3021,3021, 0, 0, 40000, 6,0.000000 }, - {3022,3022, 38, 0, 46, 46,0.000000 }, - {2441,2441, 57, 0, 73, 73,0.000000 }, - {3023,3023, 63, 0, 33, 33,0.000000 }, - {3024,3024, 74, 0, 80, 80,0.000000 }, - {3025,3025, 74, 0, 206, 206,0.000000 }, - {3026,3026, 60, 0, 300, 300,0.000000 }, - {1593,1594, 35, 0, 646, 646,0.000000 }, - {1564,1565, 35, 0, 66, 66,0.000000 }, - { 248,3027, 0, 0, 40000, 33,0.000000 }, - {1445,3028, 0, 0, 1860, 1860,0.000000 }, - {1447,3029, 0, 0, 1626, 1626,0.000000 }, - {1452,3030, 0, 0, 1740, 1740,0.000000 }, - {1544,3031, 0, 0, 160, 160,0.000000 }, - {1546,3032, 0, 0, 1913, 1913,0.000000 }, - { 398, 399, 35, 0, 600, 600,0.000000 }, - {1550,3033, 35, 0, 20, 20,0.000000 }, - {1556,1557, 35, 0, 386, 386,0.000000 }, - {1558,1559, 35, 0, 346, 346,0.000000 }, - {1570,1571, 35, 0, 360, 360,0.000000 }, - {1608,1609, 35, 0, 460, 460,0.000000 }, - {1595,1596, 35, 0, 60, 60,0.000000 }, - { 159,1597, 35, 0, 60, 60,0.000000 }, - {1610,1611, 35, 0, 60, 60,0.000000 }, - { 397,1588, 35, 0, 100, 100,0.000000 }, - {1606,1607, 35, 0, 46, 46,0.000000 }, - { 145,1576, 35, 0, 6, 6,0.000000 }, - {1612,1613, 35, 0, 60, 60,0.000000 }, - {1577,1578, 35, 0, 53, 53,0.000000 }, - {1614,1615, 35, 0, 6, 6,0.000000 }, - {1550,1551, 35, 0, 20, 20,0.000000 }, - { 364, 365, 35, 0, 20, 20,0.000000 }, - { 129,1549, 35, 0, 93, 93,0.000000 }, - { 132,1552, 35, 0, 20, 20,0.000000 }, - {1553,1554, 35, 0, 33, 33,0.000000 }, - { 129,1548, 35, 0, 86, 86,0.000000 }, - { 134,1555, 35, 0, 133, 133,0.000000 }, - {1560,1561, 35, 0, 140, 140,0.000000 }, - {1562,1563, 35, 0, 40000, 0,0.000000 }, - {1572,1573, 35, 0, 66, 66,0.000000 }, - {1574,1575, 35, 0, 60, 60,0.000000 }, - {1581,1582, 35, 0, 20, 20,0.000000 }, - { 149,1583, 35, 0, 53, 53,0.000000 }, - {1584,1585, 35, 0, 206, 206,0.000000 }, - {1591,1592, 35, 0, 386, 386,0.000000 }, - {1579,1580, 35, 0, 53, 53,0.000000 }, - {1586,1587, 35, 0, 180, 180,0.000000 }, - {1589,1590, 35, 0, 20, 20,0.000000 }, - {1600,1601, 35, 0, 140, 140,0.000000 }, - {1602,1603, 35, 0, 220, 220,0.000000 }, - {1604,1605, 35, 0, 1293, 1293,0.000000 }, - {1598,1599, 35, 0, 233, 233,0.000000 }, - { 374, 375, 35, 0, 580, 580,0.000000 }, - {1566,1567, 35, 0, 1666, 0,0.000000 }, - {2306,2307, 35, 0, 140, 140,0.000000 }, - {3034, 339, 35, 0, 4293, 4293,0.000000 }, - {2305,1548, 35, 0, 80, 80,0.000000 }, - {1595,1595, 35, 0, 60, 60,0.000000 }, - {2303,2304, 35, 0, 20, 20,0.000000 }, - {1560,2308, 35, 0, 140, 140,0.000000 }, - {2309,2310, 35, 0, 40000, 0,0.000000 }, - {1568,1568, 35, 0, 20, 20,0.000000 }, - {2311,2312, 35, 0, 66, 66,0.000000 }, - {2313,2314, 35, 0, 66, 66,0.000000 }, - {2315,2315, 35, 0, 13, 13,0.000000 }, - {2316,2316, 35, 0, 53, 53,0.000000 }, - {1612,1612, 35, 0, 60, 60,0.000000 }, - {2317,2317, 35, 0, 153, 153,0.000000 }, - {2318,2318, 35, 0, 86, 86,0.000000 }, - {2319,2319, 35, 0, 46, 46,0.000000 }, - {2320,2320, 35, 0, 46, 46,0.000000 }, - {2321,2321, 35, 0, 20, 20,0.000000 }, - {2322,2322, 35, 0, 426, 426,0.000000 }, - {2323,2323, 35, 0, 826, 826,0.000000 }, - {2324, 392, 35, 0, 20, 20,0.000000 }, - {2324, 393, 35, 0, 346, 346,0.000000 }, - {2325,2326, 35, 0, 220, 220,0.000000 }, - {2327,2328, 35, 0, 180, 180,0.000000 }, - {2329,2330, 35, 0, 160, 160,0.000000 }, - {2331,2332, 35, 0, 573, 573,0.000000 }, - {3035,3036, 35, 0, 1026, 1026,0.000000 }, - {3037,3038, 35, 0, 400, 400,0.000000 }, - {1564,1564, 35, 0, 60, 60,0.000000 }, - {3039,3039, 0, 0, 2293, 2293,0.000000 }, - {3040,3040, 0, 0, 2006, 2006,0.000000 }, - {3041,3041, 0, 0, 1226, 1226,0.000000 }, - {3042,3042, 0, 0, 1026, 1026,0.000000 }, - {3043,3043, 0, 0, 760, 760,0.000000 }, - {3044,3044, 0, 0, 546, 546,0.000000 }, - {3045,3045, 0, 0, 613, 613,0.000000 }, - {3046,3046, 0, 0, 40000, 53,0.000000 }, - {3047,3047, 0, 0, 1013, 1013,0.000000 }, - {3048,3048, 0, 0, 40000, 606,0.000000 }, - {3049,3049, 0, 0, 3626, 3626,0.000000 }, - {3050,3050, 0, 0, 993, 993,0.000000 }, - {3051,3051, 0, 0, 266, 266,0.000000 }, - {3052,3052, 0, 0, 140, 140,0.000000 }, - {3053,3053, 0, 0, 2253, 2253,0.000000 }, - {3054,3054, 0, 0, 2513, 2513,0.000000 }, - {3055,3055, 0, 0, 40000, 0,0.000000 }, - {3056,3056, 0, 0, 40000, 0,0.000000 }, - {3057,3057, 0, 0, 2146, 2146,0.000000 }, - {3058,3058, 0, 0, 40000, 0,0.000000 }, - {3059,3059, 0, 0, 40000, 6,0.000000 }, - {3060,3060, 0, 0, 40000, 6,0.000000 }, - {3061,3061, 0, 0, 460, 460,0.000000 }, - {3062,3062, 0, 0, 1846, 1846,0.000000 }, - {3063,3063, 0, 0, 933, 933,0.000000 }, - {3064,3064, 0, 0, 206, 206,0.000000 }, - {3065,3065, 0, 0, 40000, 20,0.000000 }, - {3066,3066, 0, 0, 80, 80,0.000000 }, - {3067,3067, 0, 0, 1973, 1973,0.000000 }, - {3068,3068, 0, 0, 40000, 60,0.000000 }, - {3069,3069, 0, 0, 1120, 1120,0.000000 }, - {3070,3070, 0, 0, 420, 420,0.000000 }, - {3071,3071, 0, 0, 1120, 1120,0.000000 }, - {3072,3072, 0, 0, 806, 806,0.000000 }, - {3073,3073, 0, 0, 1186, 1186,0.000000 }, - {3074,3074, 0, 0, 1900, 1900,0.000000 }, - {3075,3075, 0, 0, 40000, 0,0.000000 }, - {3076,3076, 0, 0, 1046, 1046,0.000000 }, - {3077,3077, 0, 0, 600, 600,0.000000 }, - {3078,3078, 0, 0, 146, 13,0.000000 }, - {3079,3079, 0, 0, 786, 786,0.000000 }, - {3080,3080, 0, 0, 40000, 26,0.000000 }, - {3081,3081, 0, 0, 146, 13,0.000000 }, - {3082,3082, 0, 0, 40000, 46,0.000000 }, - {3083,3083, 0, 0, 100, 100,0.000000 }, - {3084,3084, 0, 0, 1580, 1580,0.000000 }, - {3085,3085, 0, 0, 280, 280,0.000000 }, - {3086,3086, 0, 0, 40000, 80,0.000000 }, - {3087,3087, 0, 0, 40000, 73,0.000000 }, - {3088,3088, 0, 0, 40000, 66,0.000000 }, - {3089,3089, 0, 0, 40000, 73,0.000000 }, - {3090,3090, 0, 0, 40000, 0,0.000000 }, - {3091,3091, 0, 0, 40000, 6,0.000000 }, - {3092,3092, 0, 0, 40000, 6,0.000000 }, - {3093,3093, 0, 0, 246, 246,0.000000 }, - {3094,3094, 0, 0, 40000, 73,0.000000 }, - {3095,3095, 0, 0, 273, 126,0.000000 }, - {3096,3096, 0, 0, 40000, 33,0.000000 }, - {3097,3097, 0, 0, 40000, 6,0.000000 }, - {3098,3098, 0, 0, 40000, 73,0.000000 }, - {3099,3099, 0, 0, 1233, 53,0.000000 }, - {3100,3100, 0, 0, 40000, 66,0.000000 }, - {3101,3101, 0, 0, 40000, 0,0.000000 }, - {3102,3102, 0, 0, 40000, 0,0.000000 }, - {3103,3103, 0, 0, 40000, 6,0.000000 }, - {3104,3104, 0, 0, 40000, 0,0.000000 }, - {3105,3105, 0, 0, 40000, 6,0.000000 }, - {3106,3106, 0, 0, 40000, 0,0.000000 }, - {3107,3107, 0, 0, 40000, 0,0.000000 }, - {3108,3108, 0, 0, 40000, 6,0.000000 }, - {3109,3109, 0, 0, 40000, 6,0.000000 }, - {3110,3110, 0, 0, 40000, 6,0.000000 }, - {3111,3111, 0, 0, 40000, 20,0.000000 }, - {3112,3112, 0, 0, 2240, 2240,0.000000 }, - {3113,3113, 0, 0, 100, 6,0.000000 }, - {3114,3114, 0, 0, 4466, 4466,0.000000 }, - {3115,3115, 0, 0, 40000, 20,0.000000 }, - {3116,3116, 0, 0, 40000, 13,0.000000 }, - {3117,3117, 0, 0, 40000, 53,0.000000 }, - {3118,3118, 0, 0, 40000, 300,0.000000 }, - {3119,3119, 0, 0, 6906, 6906,0.000000 }, - {3120,3120, 0, 0, 40000, 33,0.000000 }, - {3121,3121, 0, 0, 40000, 6,0.000000 }, - {3122,3122, 0, 0, 1953, 1953,0.000000 }, - {3123,3123, 0, 0, 973, 973,0.000000 }, - {3124,3124, 0, 0, 2240, 6,0.000000 }, - {3125,3125, 0, 0, 1986, 1986,0.000000 }, - {3126,3126, 0, 0, 1613, 1613,0.000000 }, - {3127,3127, 0, 0, 353, 353,0.000000 }, - {3128,3128, 0, 0, 66, 66,0.000000 }, - {3129,3129, 0, 0, 5586, 5586,0.000000 }, - {3130,3130, 0, 0, 173, 173,0.000000 }, - {3131,3131, 35, 0, 120, 120,0.000000 }, - {3132,3132, 35, 0, 6, 6,0.000000 }, - {3133,3133, 35, 0, 40000, 46,0.000000 }, - {3134,3134, 35, 0, 40000, 46,0.000000 }, - {3135,3135, 35, 0, 100, 100,0.000000 }, - {3061,3061, 35, 0, 140, 140,0.000000 }, - {3136,3136, 35, 0, 20, 20,0.000000 }, - { 739, 739, 35, 0, 40, 40,0.000000 }, - {3137,3137, 35, 0, 186, 186,0.000000 }, - {3138,3138, 35, 0, 160, 160,0.000000 }, - {3139,3139, 35, 0, 93, 93,0.000000 }, - {3140,3140, 35, 0, 80, 80,0.000000 }, - {3141,3141, 35, 0, 133, 133,0.000000 }, - {3142,3142, 35, 0, 66, 66,0.000000 }, - {3143,3143, 35, 0, 133, 133,0.000000 }, - {3144,3144, 35, 0, 666, 666,0.000000 }, - {3145,3145, 35, 0, 93, 93,0.000000 }, - {3146,3146, 35, 0, 1433, 1433,0.000000 }, - {3147,3147, 35, 0, 393, 393,0.000000 }, - {3148,3148, 35, 0, 93, 93,0.000000 }, - {3149,3149, 35, 0, 1480, 1480,0.000000 }, - {3150,3150, 0, 0, 1126, 1126,0.000000 }, - {3151,3151, 0, 0, 1766, 1766,0.000000 }, - {3152,3152, 0, 0, 620, 620,0.000000 }, - {3153,3153, 0, 0, 460, 460,0.000000 }, - {3154,3154, 0, 0, 1173, 1173,0.000000 }, - {3155,3155, 0, 0, 626, 626,0.000000 }, - {3156,3156, 0, 0, 1740, 1740,0.000000 }, - {3157,3157, 0, 0, 280, 280,0.000000 }, - {3158,3158, 0, 0, 46, 46,0.000000 }, - {3159,3159, 0, 0, 280, 280,0.000000 }, - {3160,3160, 0, 0, 1153, 1153,0.000000 }, - {3161,3161, 0, 0, 40000, 0,0.000000 }, - {3162,3162, 0, 0, 40000, 6,0.000000 }, - {3163,3163, 0, 0, 40000, 46,0.000000 }, - {3164,3164, 0, 0, 40000, 0,0.000000 }, - {3165,3165, 0, 0, 40000, 6,0.000000 }, - {3166,3166, 0, 0, 2280, 2280,0.000000 }, - {3167,3167, 0, 0, 40000, 0,0.000000 }, - {3168,3168, 0, 0, 486, 486,0.000000 }, - {3169,3169, 0, 0, 600, 600,0.000000 }, - {3170,3170, 0, 0, 466, 466,0.000000 }, - {3171,3171, 0, 0, 593, 593,0.000000 }, - {3172,3172, 0, 0, 1153, 1153,0.000000 }, - {3173,3173, 0, 0, 280, 280,0.000000 }, - {3174,3174, 0, 0, 586, 586,0.000000 }, - {3175,3175, 0, 0, 206, 13,0.000000 }, - {3176,3176, 0, 0, 186, 60,0.000000 }, - {3177,3177, 0, 0, 2366, 2366,0.000000 }, - {3178,3178, 0, 0, 1700, 1700,0.000000 }, - {3179,3179, 0, 0, 46, 46,0.000000 }, - {3180,3180, 0, 0, 886, 886,0.000000 }, - {3181,3181, 0, 0, 186, 186,0.000000 }, - {3182,3182, 0, 0, 40000, 186,0.000000 }, - {3183,3183, 0, 0, 560, 560,0.000000 }, - {3184,3184, 0, 0, 1466, 1466,0.000000 }, - {3185,3185, 0, 0, 1553, 1553,0.000000 }, - {3186,3186, 0, 0, 380, 380,0.000000 }, - {3187,3187, 0, 0, 146, 146,0.000000 }, - {3188,3188, 0, 0, 146, 146,0.000000 }, - {3189,3189, 0, 0, 4726, 4726,0.000000 }, - {3190,3190, 0, 0, 40000, 6,0.000000 }, - {3191,3191, 0, 0, 1766, 1766,0.000000 }, - {3192,3192, 0, 0, 40000, 0,0.000000 }, - {3193,3193, 0, 0, 806, 806,0.000000 }, - {3194,3194, 0, 0, 1133, 1133,0.000000 }, - {3195,3195, 0, 0, 40000, 6,0.000000 }, - {3196,3196, 0, 0, 40000, 0,0.000000 }, - {3197,3197, 0, 0, 40000, 6,0.000000 }, - {3198,3198, 0, 0, 40000, 20,0.000000 }, - {3199,3199, 0, 0, 40000, 6,0.000000 }, - {3200,3200, 0, 0, 213, 213,0.000000 }, - {3201,3201, 0, 0, 40000, 106,0.000000 }, - {3202,3202, 0, 0, 1113, 1113,0.000000 }, - {3203,3203, 0, 0, 1953, 1953,0.000000 }, - {3204,3204, 0, 0, 40000, 0,0.000000 }, - {3205,3205, 0, 0, 40000, 0,0.000000 }, - {3206,3206, 0, 0, 340, 340,0.000000 }, - {3207,3207, 0, 0, 40000, 6,0.000000 }, - {3208,3208, 0, 0, 1126, 1126,0.000000 }, - {3209,3209, 0, 0, 300, 300,0.000000 }, - {3210,3210, 0, 0, 40000, 46,0.000000 }, - {3211,3211, 0, 0, 40000, 113,0.000000 }, - {3212,3212, 0, 0, 1126, 1126,0.000000 }, - {3213,3213, 0, 0, 2853, 2853,0.000000 }, - {3214,3214, 0, 0, 40000, 0,0.000000 }, - {3215,3215, 0, 0, 1286, 0,0.000000 }, - {3216,3216, 0, 0, 40000, 233,0.000000 }, - {3217,3217, 0, 0, 40000, 1640,0.000000 }, - {3218,3218, 0, 0, 40000, 240,0.000000 }, - {3219,3219, 0, 0, 1766, 1766,0.000000 }, - {3220,3220, 0, 0, 40000, 1493,0.000000 }, - {3221,3221, 0, 0, 40000, 2120,0.000000 }, - {3222,3222, 0, 0, 1226, 1226,0.000000 }, - {3223,3223, 0, 0, 306, 306,0.000000 }, - {3224,3224, 0, 0, 40000, 6,0.000000 }, - {3225,3225, 0, 0, 666, 13,0.000000 }, - {3226,3226, 0, 0, 153, 153,0.000000 }, - {3227,3227, 0, 0, 626, 626,0.000000 }, - {3228,3228, 0, 0, 140, 140,0.000000 }, - {3229,3229, 0, 0, 233, 233,0.000000 }, - { 499, 499, 0, 0, 40, 40,0.000000 }, - {3230,3230, 0, 0, 46, 46,0.000000 }, - {3231,3231, 0, 0, 146, 146,0.000000 }, - {3232,3232, 0, 0, 206, 206,0.000000 }, - {3233,3233, 0, 0, 5686, 5686,0.000000 }, - {3234,3234, 0, 0, 326, 326,0.000000 }, - { 403, 403, 0, 0, 40000, 0,0.000000 }, - {3235,3235, 0, 0, 1913, 1913,0.000000 }, - {3236,3236, 0, 0, 2080, 2080,0.000000 }, - {3237,3237, 0, 0, 2026, 2026,0.000000 }, - {3238,3238, 0, 0, 1166, 1166,0.000000 }, - {3239,3239, 0, 0, 600, 600,0.000000 }, - {3240,3240, 0, 0, 1213, 1213,0.000000 }, - {3241,3241, 0, 0, 40000, 0,0.000000 }, - {3242,3242, 0, 0, 40000, 0,0.000000 }, - {3243,3243, 0, 0, 40000, 0,0.000000 }, - {3244,3244, 0, 0, 40000, 0,0.000000 }, - {3245,3245, 0, 0, 40000, 146,0.000000 }, - {3246,3246, 0, 0, 40000, 146,0.000000 }, - {3247,3247, 0, 0, 40000, 146,0.000000 }, - {3248,3248, 0, 0, 40000, 153,0.000000 }, - {3249,3249, 0, 0, 873, 873,0.000000 }, - {3250,3250, 0, 0, 553, 553,0.000000 }, - {3251,3251, 0, 0, 873, 873,0.000000 }, - {3252,3252, 0, 0, 606, 606,0.000000 }, - {3253,3253, 0, 0, 606, 606,0.000000 }, - {3254,3254, 0, 0, 600, 600,0.000000 }, - {3255,3255, 0, 0, 1013, 1013,0.000000 }, - {3256,3256, 0, 0, 626, 626,0.000000 }, - {3257,3257, 0, 0, 40000, 0,0.000000 }, - {3258,3258, 0, 0, 40000, 0,0.000000 }, - {3259,3259, 0, 0, 40000, 66,0.000000 }, - {3260,3260, 0, 0, 40000, 66,0.000000 }, - {3261,3261, 0, 0, 40000, 20,0.000000 }, - {3262,3262, 0, 0, 1120, 1120,0.000000 }, - {3263,3263, 0, 0, 1206, 1206,0.000000 }, - {3264,3264, 0, 0, 940, 940,0.000000 }, - {3265,3265, 0, 0, 3626, 3626,0.000000 }, - {3266,3266, 0, 0, 40000, 320,0.000000 }, - {3267,3267, 0, 0, 40000, 6,0.000000 }, - {3268,3268, 0, 0, 3926, 3926,0.000000 }, - {3269,3269, 0, 0, 40000, 446,0.000000 }, - {3270,3270, 0, 0, 40000, 180,0.000000 }, - {3271,3271, 0, 0, 3426, 3426,0.000000 }, - {3272,3272, 0, 0, 2253, 2253,0.000000 }, - {3273,3273, 0, 0, 40000, 2133,0.000000 }, - {3274,3274, 0, 0, 2566, 2566,0.000000 }, - {3275,3275, 0, 0, 166, 26,0.000000 }, - {3276,3276, 0, 0, 40000, 346,0.000000 }, - {3277,3277, 0, 0, 40000, 66,0.000000 }, - {3278,3278, 0, 0, 40000, 213,0.000000 }, - {3279,3279, 0, 0, 2273, 2273,0.000000 }, - {3280,3280, 0, 0, 40000, 40,0.000000 }, - {3281,3281, 0, 0, 40000, 906,0.000000 }, - {3282,3282, 0, 0, 40000, 213,0.000000 }, - {3283,3283, 0, 0, 40000, 186,0.000000 }, - {3284,3284, 0, 0, 60, 60,0.000000 }, - {3285,3285, 0, 0, 146, 146,0.000000 }, - {3286,3286, 0, 0, 146, 13,0.000000 }, - {3287,3287, 0, 0, 786, 786,0.000000 }, - {3288,3288, 0, 0, 40000, 26,0.000000 }, - {3289,3289, 0, 0, 1580, 1580,0.000000 }, - {3290,3290, 0, 0, 653, 653,0.000000 }, - {3291,3291, 0, 0, 2400, 2400,0.000000 }, - {3292,3292, 0, 0, 1926, 1926,0.000000 }, - {3293,3293, 0, 0, 2593, 2593,0.000000 }, - {3294,3294, 0, 0, 2360, 2360,0.000000 }, - {3295,3295, 0, 0, 4933, 4933,0.000000 }, - {3296,3296, 0, 0, 593, 593,0.000000 }, - {3297,3297, 0, 0, 253, 253,0.000000 }, - {3298,3298, 0, 0, 306, 306,0.000000 }, - {3299,3299, 0, 0, 613, 613,0.000000 }, - {3300,3300, 0, 0, 1900, 1900,0.000000 }, - {3301,3301, 0, 0, 1213, 1213,0.000000 }, - {3302,3302, 0, 0, 273, 273,0.000000 }, - {3303,3303, 0, 0, 566, 566,0.000000 }, - {3304,3304, 0, 0, 40000, 6,0.000000 }, - {3305,3305, 0, 0, 40000, 6,0.000000 }, - {3306,3306, 0, 0, 40000, 6,0.000000 }, - {3307,3307, 0, 0, 40000, 6,0.000000 }, - {3308,3308, 0, 0, 40000, 6,0.000000 }, - {3309,3309, 0, 0, 40000, 0,0.000000 }, - {3310,3310, 0, 0, 40000, 0,0.000000 }, - {3311,3311, 0, 0, 40000, 0,0.000000 }, - {3312,3312, 0, 0, 40000, 6,0.000000 }, - {3313,3313, 0, 0, 40000, 53,0.000000 }, - {3314,3314, 0, 0, 40000, 73,0.000000 }, - {3315,3315, 0, 0, 40000, 0,0.000000 }, - {3316,3316, 0, 0, 40000, 0,0.000000 }, - {3317,3317, 0, 0, 40000, 0,0.000000 }, - {3318,3318, 0, 0, 40000, 80,0.000000 }, - {3319,3319, 0, 0, 40, 60,0.000000 }, - {3320,3320, 0, 0, 1320, 1320,0.000000 }, - {3321,3321, 0, 0, 40000, 126,0.000000 }, - {3322,3322, 0, 0, 273, 126,0.000000 }, - {3323,3323, 0, 0, 40000, 126,0.000000 }, - {3324,3324, 0, 0, 40000, 33,0.000000 }, - {3325,3325, 0, 0, 40000, 73,0.000000 }, - {3326,3326, 0, 0, 40, 40,0.000000 }, - {3327,3327, 0, 0, 40000, 233,0.000000 }, - {3328,3328, 0, 0, 40000, 233,0.000000 }, - {3329,3329, 0, 0, 593, 593,0.000000 }, - {3330,3330, 0, 0, 40000, 213,0.000000 }, - {3331,3331, 0, 0, 40000, 606,0.000000 }, - {3332,3332, 0, 0, 2253, 2253,0.000000 }, - {3333,3333, 0, 0, 140, 140,0.000000 }, - {3334,3334, 0, 0, 40000, 926,0.000000 }, - {3335,3335, 0, 0, 40000, 33,0.000000 }, - {3336,3336, 0, 0, 40000, 1120,0.000000 }, - {3337,3337, 0, 0, 160, 160,0.000000 }, - {3338,3338, 0, 0, 40000, 6,0.000000 }, - {3339,3339, 0, 0, 40000, 1093,0.000000 }, - {3340,3340, 0, 0, 160, 160,0.000000 }, - {3341,3341, 0, 0, 1206, 1206,0.000000 }, - {3342,3342, 0, 0, 146, 146,0.000000 }, - {3343,3343, 0, 0, 146, 146,0.000000 }, - {3344,3344, 0, 0, 140, 140,0.000000 }, - {3345,3345, 0, 0, 140, 140,0.000000 }, - {3346,3346, 0, 0, 140, 140,0.000000 }, - {3347,3347, 0, 0, 80, 80,0.000000 }, - {3348,3348, 0, 0, 40000, 33,0.000000 }, - {3349,3349, 0, 0, 1186, 1186,0.000000 }, - {3350,3350, 0, 0, 40000, 1413,0.000000 }, - {3351,3351, 0, 0, 1226, 1226,0.000000 }, - {3352,3352, 0, 0, 40, 40,0.000000 }, - {3353,3353, 0, 0, 60, 60,0.000000 }, - {3354,3354, 0, 0, 100, 100,0.000000 }, - {3355,3355, 0, 0, 246, 246,0.000000 }, - {3356,3356, 0, 0, 1140, 1140,0.000000 }, - { 142, 142, 20, 0, 20, 20,0.000000 }, - {3357,1451, 0, 0, 613, 613,0.000000 }, - {3358,3359, 0, 0, 1740, 1740,0.000000 }, - {3360,1455, 0, 0, 280, 280,0.000000 }, - {3361,1463, 0, 0, 40000, 133,0.000000 }, - { 225,3362, 0, 0, 2026, 2026,0.000000 }, - {3363,1545, 0, 0, 153, 153,0.000000 }, - {3364,1547, 0, 0, 40000, 60,0.000000 }, - {3365,3366, 39, 0, 13, 13,0.000000 }, - {3367, 368, 58, 0, 46, 46,0.000000 }, - {3368,1551, 48, 0, 93, 93,0.000000 }, - {3368,3033, 49, 0, 73, 73,0.000000 }, - {3368,3033, 51, 0, 153, 153,0.000000 }, - {3368,3033, 54, 0, 140, 140,0.000000 }, - {3368,3033, 57, 0, 126, 126,0.000000 }, - {3368,3033, 60, 0, 133, 133,0.000000 }, - {3369,3370, 70, 0, 893, 893,0.000000 }, - {1564,1565, 80, 0, 66, 66,0.000000 }, - {3371,1571, 44, 0, 520, 520,0.000000 }, - {3372,3372, 0, 0, 1486, 1486,0.000000 }, - {3373,3373, 0, 0, 1806, 1806,0.000000 }, - {3374,3374, 0, 0, 633, 633,0.000000 }, - {3375,3375, 0, 0, 1273, 1273,0.000000 }, - {3376,3376, 0, 0, 1553, 1553,0.000000 }, - {3377,3377, 0, 0, 1206, 1206,0.000000 }, - {3378,3378, 0, 0, 313, 313,0.000000 }, - {3379,3379, 0, 0, 1486, 1486,0.000000 }, - {3380,3380, 0, 0, 626, 626,0.000000 }, - {3381,3381, 0, 0, 1846, 1846,0.000000 }, - {3382,3382, 0, 0, 300, 300,0.000000 }, - {3383,3383, 0, 0, 1740, 1740,0.000000 }, - {3384,3384, 0, 0, 513, 513,0.000000 }, - {3385,3385, 0, 0, 46, 46,0.000000 }, - {3386,3386, 0, 0, 1226, 1226,0.000000 }, - {3387,3387, 0, 0, 333, 333,0.000000 }, - {3388,3388, 0, 0, 40000, 300,0.000000 }, - {3389,3389, 0, 0, 40000, 533,0.000000 }, - {3390,3390, 0, 0, 40000, 126,0.000000 }, - {3391,3391, 0, 0, 40000, 0,0.000000 }, - {3392,3392, 0, 0, 40000, 33,0.000000 }, - {3393,3393, 0, 0, 40000, 6,0.000000 }, - {3394,3394, 0, 0, 40000, 6,0.000000 }, - {3395,3395, 0, 0, 3880, 6,0.000000 }, - {3396,3396, 0, 0, 1066, 1066,0.000000 }, - {3397,3397, 0, 0, 4086, 4086,0.000000 }, - {3398,3398, 0, 0, 866, 866,0.000000 }, - {3399,3399, 0, 0, 466, 466,0.000000 }, - {3400,3400, 0, 0, 420, 420,0.000000 }, - {3401,3401, 0, 0, 40000, 73,0.000000 }, - {3402,3402, 0, 0, 40000, 20,0.000000 }, - {3403,3403, 0, 0, 40000, 26,0.000000 }, - {3404,3404, 0, 0, 4266, 4266,0.000000 }, - {3405,3405, 0, 0, 40000, 0,0.000000 }, - {3406,3406, 0, 0, 253, 253,0.000000 }, - {3407,3407, 0, 0, 380, 380,0.000000 }, - {3408,3408, 0, 0, 573, 573,0.000000 }, - {3409,3409, 0, 0, 280, 280,0.000000 }, - {3410,3410, 0, 0, 40000, 6,0.000000 }, - {3411,3411, 0, 0, 1933, 1933,0.000000 }, - {3412,3412, 0, 0, 40000, 140,0.000000 }, - {3413,3413, 0, 0, 40000, 140,0.000000 }, - {3414,3414, 0, 0, 40000, 40,0.000000 }, - {3415,3415, 0, 0, 353, 353,0.000000 }, - {3416,3416, 0, 0, 40000, 166,0.000000 }, - {3417,3417, 0, 0, 273, 273,0.000000 }, - {3418,3418, 0, 0, 126, 126,0.000000 }, - {3419,3419, 0, 0, 146, 146,0.000000 }, - {3420,3420, 0, 0, 40000, 213,0.000000 }, - {3421,3421, 0, 0, 40000, 173,0.000000 }, - {3422,3422, 0, 0, 40000, 206,0.000000 }, - {3423,3423, 0, 0, 40000, 213,0.000000 }, - {3424,3424, 0, 0, 40000, 153,0.000000 }, - {3425,3425, 0, 0, 40000, 106,0.000000 }, - {3426,3426, 0, 0, 40000, 6,0.000000 }, - {3427,3427, 0, 0, 233, 233,0.000000 }, - {3428,3428, 0, 0, 40000, 6,0.000000 }, - {3429,3429, 0, 0, 11193, 13,0.000000 }, - {3430,3430, 0, 0, 40000, 126,0.000000 }, - {3431,3431, 0, 0, 40000, 13,0.000000 }, - {3432,3432, 0, 0, 40000, 6,0.000000 }, - {3433,3433, 0, 0, 40000, 0,0.000000 }, - {3434,3434, 0, 0, 40000, 0,0.000000 }, - {3435,3435, 0, 0, 40000, 0,0.000000 }, - {3436,3436, 0, 0, 40000, 0,0.000000 }, - {3437,3437, 0, 0, 40000, 0,0.000000 }, - {3438,3438, 0, 0, 40000, 0,0.000000 }, - {3439,3439, 0, 0, 6013, 6013,0.000000 }, - {3440,3440, 0, 0, 40000, 0,0.000000 }, - {3441,3441, 0, 0, 40000, 0,0.000000 }, - {3442,3442, 0, 0, 293, 293,0.000000 }, - {3443,3443, 0, 0, 40000, 6,0.000000 }, - {3444,3444, 0, 0, 40000, 20,0.000000 }, - {3445,3445, 0, 0, 40000, 0,0.000000 }, - {3446,3446, 0, 0, 40000, 0,0.000000 }, - {3447,3447, 0, 0, 40000, 0,0.000000 }, - {3448,3448, 0, 0, 40000, 0,0.000000 }, - {3449,3449, 0, 0, 40000, 20,0.000000 }, - {3450,3450, 0, 0, 40000, 153,0.000000 }, - {3451,3451, 0, 0, 440, 440,0.000000 }, - {3452,3452, 0, 0, 3253, 3253,0.000000 }, - {3453,3453, 0, 0, 3946, 3946,0.000000 }, - {3454,3454, 0, 0, 140, 140,0.000000 }, - {3455,3455, 0, 0, 40000, 20,0.000000 }, - {3456,3456, 0, 0, 40000, 33,0.000000 }, - {3457,3457, 0, 0, 40000, 20,0.000000 }, - {3458,3458, 0, 0, 40000, 26,0.000000 }, - {3459,3459, 0, 0, 40000, 20,0.000000 }, - {3460,3460, 0, 0, 786, 786,0.000000 }, - {3461,3461, 0, 0, 2560, 2560,0.000000 }, - {3462,3462, 0, 0, 40000, 26,0.000000 }, - {3463,3463, 0, 0, 40000, 580,0.000000 }, - {3464,3464, 0, 0, 40000, 2393,0.000000 }, - {3465,3465, 0, 0, 40000, 53,0.000000 }, - {3466,3466, 0, 0, 40000, 33,0.000000 }, - {3467,3467, 0, 0, 40000, 193,0.000000 }, - {3468,3468, 0, 0, 40000, 280,0.000000 }, - {3469,3469, 0, 0, 40000, 86,0.000000 }, - {3470,3470, 0, 0, 40000, 820,0.000000 }, - {3471,3471, 0, 0, 40000, 286,0.000000 }, - {3472,3472, 0, 0, 40000, 1100,0.000000 }, - {3473,3473, 0, 0, 40000, 1073,0.000000 }, - {3474,3474, 0, 0, 40000, 1173,0.000000 }, - {3475,3475, 0, 0, 340, 340,0.000000 }, - {3476,3476, 0, 0, 4846, 4846,0.000000 }, - {3477,3477, 0, 0, 40000, 0,0.000000 }, - {3478,3478, 0, 0, 4846, 4846,0.000000 }, - {3479,3479, 0, 0, 606, 606,0.000000 }, - {3480,3480, 0, 0, 106, 106,0.000000 }, - {3481,3481, 0, 0, 40000, 0,0.000000 }, - {3482,3482, 0, 0, 40000, 73,0.000000 }, - {3483,3483, 0, 0, 40000, 0,0.000000 }, - {3484,3484, 0, 0, 586, 586,0.000000 }, - {3485,3485, 0, 0, 73, 73,0.000000 }, - {3486,3486, 0, 0, 460, 460,0.000000 }, - {3487,3487, 0, 0, 40, 40,0.000000 }, - {3488,3488, 0, 0, 526, 526,0.000000 }, - {3489,3489, 0, 0, 540, 540,0.000000 }, - {3490,3490, 0, 0, 253, 253,0.000000 }, - {3491,3491, 0, 0, 2280, 2280,0.000000 }, - {3492,3492, 0, 0, 73, 73,0.000000 }, - {3493,3493, 0, 0, 40000, 73,0.000000 }, - {3494,3494, 0, 0, 40000, 2220,0.000000 }, - {3495,3495, 0, 0, 146, 146,0.000000 }, - {3496,3496, 0, 0, 40000, 13,0.000000 }, - {3497,3497, 0, 0, 380, 13,0.000000 }, - {3498,3498, 0, 0, 40000, 2220,0.000000 }, - {3499,3499, 0, 0, 40000, 146,0.000000 }, - {3500,3500, 0, 0, 1513, 13,0.000000 }, - { 739, 739, 46, 0, 53, 53,0.000000 }, - {3501,3501, 47, 0, 106, 106,0.000000 }, - {3502,3502, 64, 0, 26, 26,0.000000 }, - {3503,3503, 40, 0, 106, 106,0.000000 }, - {3504,3504, 48, 0, 13, 13,0.000000 }, - {3505,3505, 48, 0, 80, 80,0.000000 }, - {3506,3506, 46, 0, 86, 86,0.000000 }, - {3507,3507,111, 0, 33, 33,0.000000 }, - {3508,3508, 49, 0, 140, 140,0.000000 }, - {3509,3509, 56, 0, 33, 33,0.000000 }, - {3510,3510, 52, 0, 140, 140,0.000000 }, - {3511,3511, 96, 0, 440, 440,0.000000 }, - {3510,3510, 54, 0, 140, 140,0.000000 }, - {3512,3512, 57, 0, 260, 260,0.000000 }, - {3513,3513, 82, 0, 486, 486,0.000000 }, - {3510,3510, 60, 0, 153, 153,0.000000 }, - {3514,3514, 60, 0, 606, 606,0.000000 }, - {3515,3515, 92, 0, 60, 60,0.000000 }, - {3516,3516, 60, 0, 46, 46,0.000000 }, - {3517,3517, 58, 0, 40, 40,0.000000 }, - {3518,3518, 22, 0, 53, 53,0.000000 }, - {3519,3519, 60, 0, 613, 613,0.000000 }, - {3520,3520, 72, 0, 80, 80,0.000000 }, - {3521,3521, 77, 0, 80, 80,0.000000 }, - {3522,3522, 70, 0, 73, 73,0.000000 }, - {3523,3523, 75, 0, 60, 60,0.000000 }, - {3524,3524, 69, 0, 140, 140,0.000000 }, - {3525,3525, 59, 0, 113, 113,0.000000 }, - {3526,3526, 48, 0, 153, 153,0.000000 }, - {3527,3527, 89, 0, 133, 133,0.000000 }, - {3528,3528, 84, 0, 260, 260,0.000000 }, - {3529,3529, 33, 0, 93, 93,0.000000 }, - {3530,3530, 55, 0, 86, 86,0.000000 }, - {3531,3531, 58, 0, 186, 186,0.000000 }, - {3532,3532, 52, 0, 166, 166,0.000000 }, - {3533,3533, 57, 0, 46, 46,0.000000 }, - {3534,3534, 57, 0, 73, 73,0.000000 }, - {3535,3535, 85, 0, 60, 60,0.000000 }, - {3536,3536, 68, 0, 40, 40,0.000000 }, - {3536,3536, 61, 0, 60, 60,0.000000 }, - {3537,3537, 64, 0, 93, 93,0.000000 }, - {3538,3538, 44, 0, 386, 386,0.000000 }, - {3539,3539,100, 0, 80, 80,0.000000 }, - {3540,3540,100, 0, 306, 306,0.000000 }, - {3541,3541, 0, 0, 1400, 1400,0.000000 }, - {3542,3542, 0, 0, 253, 253,0.000000 }, - {3543,3543, 0, 0, 460, 460,0.000000 }, - {3544,3544, 0, 0, 1226, 1226,0.000000 }, - {3545,3545, 0, 0, 886, 886,0.000000 }, - {3546,3546, 0, 0, 40, 40,0.000000 }, - {3547,3547, 0, 0, 2406, 2406,0.000000 }, - {3548,3548, 0, 0, 1180, 1180,0.000000 }, - {3549,3549, 0, 0, 40000, 0,0.000000 }, - {3550,3550, 0, 0, 40000, 0,0.000000 }, - {3551,3551, 0, 0, 40000, 33,0.000000 }, - {3552,3552, 0, 0, 40000, 0,0.000000 }, - {3553,3553, 0, 0, 40000, 6,0.000000 }, - {3554,3554, 0, 0, 1553, 1553,0.000000 }, - {3555,3555, 0, 0, 40000, 0,0.000000 }, - {3556,3556, 0, 0, 573, 573,0.000000 }, - {3557,3557, 0, 0, 526, 526,0.000000 }, - {3558,3558, 0, 0, 940, 940,0.000000 }, - {3559,3559, 0, 0, 606, 606,0.000000 }, - {3560,3560, 0, 0, 40000, 6,0.000000 }, - {3561,3561, 0, 0, 40000, 0,0.000000 }, - {3562,3562, 0, 0, 1120, 1120,0.000000 }, - {3563,3563, 0, 0, 700, 700,0.000000 }, - {3564,3564, 0, 0, 66, 66,0.000000 }, - {3565,3565, 0, 0, 620, 620,0.000000 }, - {3566,3566, 0, 0, 286, 286,0.000000 }, - {3567,3567, 0, 0, 40000, 73,0.000000 }, - {3568,3568, 0, 0, 80, 80,0.000000 }, - {3569,3569, 0, 0, 186, 186,0.000000 }, - {3570,3570, 0, 0, 1506, 1506,0.000000 }, - {3571,3571, 0, 0, 40000, 0,0.000000 }, - {3572,3572, 0, 0, 40000, 186,0.000000 }, - {3573,3573, 0, 0, 126, 126,0.000000 }, - {3574,3574, 0, 0, 40000, 106,0.000000 }, - {3575,3575, 0, 0, 166, 166,0.000000 }, - {3576,3576, 0, 0, 80, 80,0.000000 }, - {3577,3577, 0, 0, 453, 13,0.000000 }, - {3578,3578, 0, 0, 40000, 0,0.000000 }, - {3579,3579, 0, 0, 40000, 6,0.000000 }, - {3580,3580, 0, 0, 2020, 2020,0.000000 }, - {3581,3581, 0, 0, 1646, 1646,0.000000 }, - {3582,3582, 0, 0, 166, 166,0.000000 }, - {3583,3583, 0, 0, 40000, 0,0.000000 }, - {3584,3584, 0, 0, 146, 146,0.000000 }, - {3585,3585, 0, 0, 340, 340,0.000000 }, - {3586,3586, 0, 0, 40000, 0,0.000000 }, - {3587,3587, 0, 0, 100, 13,0.000000 }, - {3588,3588, 0, 0, 5013, 5013,0.000000 }, - {3589,3589, 0, 0, 40000, 6,0.000000 }, - {3590,3590, 0, 0, 1766, 1766,0.000000 }, - {3591,3591, 0, 0, 4186, 4186,0.000000 }, - {3592,3592, 0, 0, 700, 700,0.000000 }, - {3593,3593, 0, 0, 940, 940,0.000000 }, - {3594,3594, 0, 0, 246, 246,0.000000 }, - {3595,3595, 0, 0, 40000, 6,0.000000 }, - {3596,3596, 0, 0, 40000, 6,0.000000 }, - {3597,3597, 0, 0, 40000, 6,0.000000 }, - {3598,3598, 0, 0, 40000, 0,0.000000 }, - {3599,3599, 0, 0, 40000, 306,0.000000 }, - {3600,3600, 0, 0, 40000, 53,0.000000 }, - {3601,3601, 0, 0, 40000, 6,0.000000 }, - {3602,3602, 0, 0, 40000, 233,0.000000 }, - {3603,3603, 0, 0, 120, 120,0.000000 }, - {3604,3604, 0, 0, 40000, 6,0.000000 }, - {3605,3605, 0, 0, 40000, 153,0.000000 }, - {3606,3606, 0, 0, 1086, 1086,0.000000 }, - {3607,3607, 0, 0, 1900, 1900,0.000000 }, - {3608,3608, 0, 0, 40000, 0,0.000000 }, - {3609,3609, 0, 0, 40000, 13,0.000000 }, - {3610,3610, 0, 0, 253, 253,0.000000 }, - {3611,3611, 0, 0, 40000, 6,0.000000 }, - {3612,3612, 0, 0, 40000, 126,0.000000 }, - {3613,3613, 0, 0, 3680, 3680,0.000000 }, - {3614,3614, 0, 0, 660, 660,0.000000 }, - {3615,3615, 0, 0, 40000, 206,0.000000 }, - {3616,3616, 0, 0, 40000, 106,0.000000 }, - {3617,3617, 0, 0, 546, 546,0.000000 }, - {3618,3618, 0, 0, 126, 6,0.000000 }, - {3619,3619, 0, 0, 40000, 1306,0.000000 }, - {3620,3620, 0, 0, 1240, 1240,0.000000 }, - {3621,3621, 0, 0, 1400, 1400,0.000000 }, - {3622,3622, 0, 0, 40000, 0,0.000000 }, - {3623,3623, 0, 0, 40000, 0,0.000000 }, - {3624,3624, 0, 0, 40000, 833,0.000000 }, - {3625,3625, 0, 0, 40000, 240,0.000000 }, - {3626,3626, 0, 0, 40000, 1973,0.000000 }, - {3627,3627, 0, 0, 4466, 4466,0.000000 }, - {3628,3628, 0, 0, 13, 13,0.000000 }, - {3629,3629, 0, 0, 40000, 2206,0.000000 }, - {3630,3630, 0, 0, 40000, 1180,0.000000 }, - {3631,3631, 0, 0, 4933, 4933,0.000000 }, - {3632,3632, 0, 0, 200, 200,0.000000 }, - {3633,3633, 0, 0, 1226, 1226,0.000000 }, - {3634,3634, 0, 0, 273, 273,0.000000 }, - {3635,3635, 0, 0, 353, 13,0.000000 }, - {3636,3636, 0, 0, 40000, 6,0.000000 }, - {3637,3637, 0, 0, 60, 60,0.000000 }, - {3638,3638, 0, 0, 160, 160,0.000000 }, - {3639,3639, 0, 0, 313, 313,0.000000 }, - {3640,3640, 0, 0, 46, 46,0.000000 }, - {3641,3641, 0, 0, 313, 313,0.000000 }, - {3642,3642, 0, 0, 40, 40,0.000000 }, - {3643,3643, 0, 0, 86, 86,0.000000 }, - {3644,3644, 0, 0, 46, 46,0.000000 }, - {3645,3645, 0, 0, 146, 146,0.000000 }, - {3646,3646, 0, 0, 146, 146,0.000000 }, - {3647,3647, 0, 0, 220, 220,0.000000 }, - {3648,3648, 0, 0, 86, 86,0.000000 }, - {3649,3649, 0, 0, 40000, 320,0.000000 }, - {3650,3650, 0, 0, 40000, 6,0.000000 }, - {3651,3651, 0, 0, 40000, 0,0.000000 }, - {3652,3652, 0, 0, 300, 300,0.000000 }, - {3653,3653, 0, 0, 2940, 2940,0.000000 }, - {3654,3654, 0, 0, 1233, 1233,0.000000 }, - {3655,3655, 0, 0, 3840, 3840,0.000000 }, - {3656,3656, 0, 0, 2280, 2280,0.000000 }, - {3657,3657, 0, 0, 1793, 1793,0.000000 }, - {3658,3658, 0, 0, 1120, 1120,0.000000 }, - {3659,3659, 0, 0, 1013, 1013,0.000000 }, - {3660,3660, 0, 0, 1233, 1233,0.000000 }, - {3661,3661, 0, 0, 600, 600,0.000000 }, - {3662,3662, 0, 0, 280, 280,0.000000 }, - {3663,3663, 0, 0, 266, 266,0.000000 }, - {3664,3664, 0, 0, 1740, 1740,0.000000 }, - {3665,3665, 0, 0, 246, 246,0.000000 }, - {3666,3666, 0, 0, 140, 140,0.000000 }, - {3667,3667, 0, 0, 1166, 1166,0.000000 }, - {3668,3668, 0, 0, 273, 273,0.000000 }, - {3669,3669, 0, 0, 40000, 0,0.000000 }, - {3670,3670, 0, 0, 40000, 0,0.000000 }, - {3671,3671, 0, 0, 313, 313,0.000000 }, - {3672,3672, 0, 0, 40000, 6,0.000000 }, - {3673,3673, 0, 0, 40000, 133,0.000000 }, - {3674,3674, 0, 0, 40000, 133,0.000000 }, - {3675,3675, 0, 0, 40000, 66,0.000000 }, - {3676,3676, 0, 0, 40000, 133,0.000000 }, - {3677,3677, 0, 0, 940, 940,0.000000 }, - {3678,3678, 0, 0, 760, 760,0.000000 }, - {3679,3679, 0, 0, 1200, 1200,0.000000 }, - {3680,3680, 0, 0, 566, 566,0.000000 }, - {3681,3681, 0, 0, 573, 573,0.000000 }, - {3682,3682, 0, 0, 40000, 0,0.000000 }, - {3683,3683, 0, 0, 1353, 1353,0.000000 }, - {3684,3684, 0, 0, 2226, 2226,0.000000 }, - {3685,3685, 0, 0, 866, 866,0.000000 }, - {3686,3686, 0, 0, 2293, 2293,0.000000 }, - {3687,3687, 0, 0, 2113, 2113,0.000000 }, - {3688,3688, 0, 0, 1280, 1280,0.000000 }, - {3689,3689, 0, 0, 886, 886,0.000000 }, - {3690,3690, 0, 0, 833, 833,0.000000 }, - {3691,3691, 0, 0, 886, 886,0.000000 }, - {3692,3692, 0, 0, 940, 940,0.000000 }, - {3693,3693, 0, 0, 40000, 260,0.000000 }, - {3694,3694, 0, 0, 166, 13,0.000000 }, - {3695,3695, 0, 0, 40000, 26,0.000000 }, - {3696,3696, 0, 0, 146, 146,0.000000 }, - {3697,3697, 0, 0, 40000, 86,0.000000 }, - {3698,3698, 0, 0, 940, 940,0.000000 }, - {3699,3699, 0, 0, 100, 100,0.000000 }, - {3700,3700, 0, 0, 513, 513,0.000000 }, - {3701,3701, 0, 0, 40000, 286,0.000000 }, - {3702,3702, 0, 0, 40000, 133,0.000000 }, - {3703,3703, 0, 0, 40000, 233,0.000000 }, - {3704,3704, 0, 0, 40000, 40,0.000000 }, - {3705,3705, 0, 0, 3413, 3413,0.000000 }, - {3706,3706, 0, 0, 3413, 3413,0.000000 }, - {3707,3707, 0, 0, 253, 253,0.000000 }, - {3708,3708, 0, 0, 60, 73,0.000000 }, - {3709,3709, 0, 0, 40000, 66,0.000000 }, - {3710,3710, 0, 0, 40000, 33,0.000000 }, - {3711,3711, 0, 0, 40000, 0,0.000000 }, - {3712,3712, 0, 0, 40000, 126,0.000000 }, - {3713,3713, 0, 0, 40000, 6,0.000000 }, - {3714,3714, 0, 0, 40000, 0,0.000000 }, - {3715,3715, 0, 0, 40000, 126,0.000000 }, - {3716,3716, 0, 0, 40000, 26,0.000000 }, - {3717,3717, 0, 0, 40000, 20,0.000000 }, - {3718,3718, 0, 0, 40000, 20,0.000000 }, - {3719,3719, 0, 0, 40000, 0,0.000000 }, - {3720,3720, 0, 0, 40000, 0,0.000000 }, - {3721,3721, 0, 0, 40000, 6,0.000000 }, - {3722,3722, 0, 0, 40000, 33,0.000000 }, - {3723,3723, 0, 0, 40000, 6,0.000000 }, - {3724,3724, 0, 0, 40000, 6,0.000000 }, - {3725,3725, 0, 0, 40000, 20,0.000000 }, - {3726,3726, 0, 0, 40000, 33,0.000000 }, - {3727,3727, 0, 0, 100, 100,0.000000 }, - {3728,3728, 0, 0, 40000, 26,0.000000 }, - {3729,3729, 0, 0, 40000, 26,0.000000 }, - {3730,3730, 0, 0, 40000, 53,0.000000 }, - {3731,3731, 0, 0, 40000, 0,0.000000 }, - {3732,3732, 0, 0, 40000, 0,0.000000 }, - {3733,3733, 0, 0, 40000, 26,0.000000 }, - {3734,3734, 0, 0, 40000, 13,0.000000 }, - {3735,3735, 0, 0, 40000, 6,0.000000 }, - {3736,3736, 0, 0, 3766, 3766,0.000000 }, - {3737,3737, 0, 0, 40000, 140,0.000000 }, - {3738,3738, 0, 0, 40000, 13,0.000000 }, - {3739,3739, 0, 0, 40000, 233,0.000000 }, - {3740,3740, 0, 0, 40000, 413,0.000000 }, - {3741,3741, 0, 0, 1873, 26,0.000000 }, - {3742,3742, 0, 0, 40000, 566,0.000000 }, - {3743,3743, 0, 0, 753, 753,0.000000 }, - {3744,3744, 0, 0, 1166, 13,0.000000 }, - {3745,3745, 0, 0, 40000, 566,0.000000 }, - {3746,3746, 0, 0, 40000, 53,0.000000 }, - {3747,3747, 0, 0, 1020, 1020,0.000000 }, - {3748,3748, 0, 0, 40000, 340,0.000000 }, - {3749,3749, 0, 0, 440, 440,0.000000 }, - {3750,3750, 0, 0, 40000, 106,0.000000 }, - {3751,3751, 0, 0, 2286, 2286,0.000000 }, - {3752,3752, 0, 0, 40000, 966,0.000000 }, - {3753,3753, 0, 0, 40000, 766,0.000000 }, - {3754,3754, 0, 0, 40000, 6,0.000000 }, - {3755,3755, 0, 0, 4933, 4933,0.000000 }, - {3756,3756, 0, 0, 1126, 1126,0.000000 }, - {3757,3757, 0, 0, 273, 273,0.000000 }, - {3758,3758, 0, 0, 546, 546,0.000000 }, - {3759,3759, 0, 0, 280, 280,0.000000 }, - {3760,3760, 0, 0, 40000, 6,0.000000 }, - {3761,3761, 0, 0, 40000, 6,0.000000 }, - {3762,3762, 0, 0, 40000, 0,0.000000 }, - {3763,3763, 0, 0, 1106, 1106,0.000000 }, - {3764,3764, 0, 0, 86, 86,0.000000 }, - {3765,3765, 0, 0, 280, 280,0.000000 }, - {3766,3766, 0, 0, 53, 53,0.000000 }, - {3767,3767, 0, 0, 40, 40,0.000000 }, - {3768,3768, 0, 0, 60, 60,0.000000 }, - {3769,3769, 0, 0, 253, 253,0.000000 }, - {3770,3770, 0, 0, 1213, 1213,0.000000 }, - {3771,3771, 0, 0, 293, 293,0.000000 }, - {3772,3772, 0, 0, 153, 153,0.000000 }, - {3773,3773, 0, 0, 4586, 4586,0.000000 }, - {3774,3774, 0, 0, 146, 146,0.000000 }, - {3775,3775, 0, 0, 40000, 0,0.000000 }, - {3776,3776, 0, 0, 146, 146,0.000000 }, - {3777,3777, 0, 0, 40000, 113,0.000000 }, - {3778,3778, 0, 0, 153, 153,0.000000 }, - {3779,3779, 0, 0, 1726, 13,0.000000 }, - { 738, 738, 44, 0, 40, 40,0.000000 }, - {3780,3780, 36, 0, 33, 33,0.000000 }, - {3781,3781, 32, 0, 6, 6,0.000000 }, - {2030,2030, 60, 0, 86, 86,0.000000 }, - {3782,3782, 24, 0, 6, 6,0.000000 }, - {3783,3783, 60, 0, 26, 26,0.000000 }, - {3784,3784, 44, 0, 140, 140,0.000000 }, - { 132, 132, 44, 0, 20, 20,0.000000 }, - {3785,3785, 47, 0, 153, 153,0.000000 }, - { 152, 152, 44, 0, 86, 86,0.000000 }, - {3784,3784, 50, 0, 160, 160,0.000000 }, - { 139, 139, 44, 0, 86, 86,0.000000 }, - {3784,3784, 54, 0, 160, 160,0.000000 }, - {3784,3784, 57, 0, 160, 160,0.000000 }, - {3786,3786, 60, 0, 606, 606,0.000000 }, - {3784,3784, 60, 0, 166, 166,0.000000 }, - {3787,3787, 60, 0, 606, 606,0.000000 }, - {3788,3788, 60, 0, 626, 626,0.000000 }, - {3789,3789, 60, 0, 626, 626,0.000000 }, - {3790,3790, 60, 0, 606, 606,0.000000 }, - {3791,3791, 44, 0, 300, 300,0.000000 }, - {2037,2037, 44, 0, 40, 40,0.000000 }, - { 144, 144, 44, 0, 40, 40,0.000000 }, - {2038,2038, 44, 0, 13, 13,0.000000 }, - {3792,3792, 44, 0, 33, 33,0.000000 }, - {3793,3793, 44, 0, 60, 60,0.000000 }, - {3794,3794, 45, 0, 80, 80,0.000000 }, - {3795,3795, 33, 0, 100, 100,0.000000 }, - {3796,3796, 56, 0, 153, 153,0.000000 }, - {3796,3796, 51, 0, 153, 153,0.000000 }, - {3797,3797, 44, 0, 40, 40,0.000000 }, - {3798,3798, 44, 0, 200, 200,0.000000 }, - {3534,3534, 56, 0, 73, 73,0.000000 }, - { 158, 158, 68, 0, 20, 20,0.000000 }, - {3799,3799, 51, 0, 160, 160,0.000000 }, - {3800,3800, 46, 0, 153, 153,0.000000 }, - {3801,3801, 44, 0, 160, 160,0.000000 }, - {3802,3802, 44, 0, 1233, 1233,0.000000 }, - { 152, 152, 45, 0, 80, 80,0.000000 }, - {3803,3803, 0, 0, 40000, 20,0.000000 }, - {3804,3804, 0, 0, 40000, 66,0.000000 }, - {3805,3805, 0, 0, 40000, 0,0.000000 }, - {3806,3806, 0, 0, 40000, 0,0.000000 }, - {3807,3807, 0, 0, 40000, 20,0.000000 }, - {3808,3808, 0, 0, 1226, 1226,0.000000 }, - {3809,3809, 0, 0, 546, 546,0.000000 }, - {3810,3810, 0, 0, 280, 280,0.000000 }, - {3811,3811, 0, 0, 60, 60,0.000000 }, - {3812,3812, 0, 0, 1213, 1213,0.000000 }, - {3780,3780, 45, 0, 440, 440,0.000000 }, - {3061,3061, 45, 0, 606, 606,0.000000 }, - {3813,3813, 60, 0, 20, 20,0.000000 }, - {3781,3781, 60, 0, 6, 6,0.000000 }, - {3814,3814, 44, 0, 173, 173,0.000000 }, - {3815,3815, 57, 0, 46, 46,0.000000 }, - {3816,3816, 56, 0, 73, 73,0.000000 }, - {3817,3817, 60, 0, 20, 20,0.000000 }, - {3818,3818, 60, 0, 20, 20,0.000000 }, - {3517,3517, 45, 0, 40, 40,0.000000 }, - {3819,3819, 0, 0, 820, 820,0.000000 }, - {3820,3820, 0, 0, 573, 573,0.000000 }, - {3821,3821, 0, 0, 473, 473,0.000000 }, - {3822,3822, 0, 0, 1020, 1020,0.000000 }, - {3823,3823, 0, 0, 40000, 393,0.000000 }, - {3824,3825, 0, 1, 40000, 266,0.078125 }, - {3826,3826, 0, 0, 3833, 13,0.000000 }, - {3827,3827, 0, 0, 40000, 406,0.000000 }, - {3828,1172, 0, 1, 40000, 320,0.156250 }, - {3829,3829, 0, 0, 40000, 13,0.000000 }, - {3830,3830, 0, 0, 120, 120,0.000000 }, - {3831,3831, 32, 0, 20, 20,0.000000 }, - {3832,3832, 36, 0, 46, 46,0.000000 }, - {3833,3833, 88, 0, 93, 93,0.000000 }, - {3834,3834, 0, 0, 1660, 1660,0.000000 }, - {3835,3835, 0, 0, 1746, 1746,0.000000 }, - {3836,3836, 0, 0, 1980, 1980,0.000000 }, - {3837,3837, 0, 0, 1553, 1553,0.000000 }, - {3838,3838, 0, 0, 1233, 1233,0.000000 }, - {3839,3839, 0, 0, 1980, 1980,0.000000 }, - {3840,3840, 0, 0, 940, 940,0.000000 }, - {3841,3841, 0, 0, 1740, 1740,0.000000 }, - {3842,3842, 0, 0, 40000, 133,0.000000 }, - {3843,3843, 0, 0, 40000, 26,0.000000 }, - {3844,3844, 0, 0, 40000, 60,0.000000 }, - {3845,3845, 0, 0, 40000, 320,0.000000 }, - {3846,3846, 0, 0, 40000, 53,0.000000 }, - {3847,3847, 0, 0, 40000, 160,0.000000 }, - {3848,3848, 0, 0, 40000, 106,0.000000 }, - {3849,3849, 0, 0, 1026, 1026,0.000000 }, - {3850,3850, 0, 0, 1826, 1826,0.000000 }, - {3851,3851, 0, 0, 1813, 1813,0.000000 }, - {3852,3852, 0, 0, 1013, 1013,0.000000 }, - {3853,3853, 0, 0, 40000, 0,0.000000 }, - {3854,3854, 0, 0, 40000, 53,0.000000 }, - {3855,3855, 0, 0, 40000, 53,0.000000 }, - {3856,3856, 0, 0, 4200, 4200,0.000000 }, - {3857,3857, 0, 0, 40000, 106,0.000000 }, - {3858,3858, 0, 0, 1746, 1746,0.000000 }, - {3859,3859, 0, 0, 40000, 120,0.000000 }, - {3860,3860, 0, 0, 2400, 2400,0.000000 }, - {3861,3861, 0, 0, 4606, 4606,0.000000 }, - {3862,3862, 0, 0, 1740, 1740,0.000000 }, - {3863,3863, 0, 0, 40000, 66,0.000000 }, - {3864,3864, 0, 0, 40000, 46,0.000000 }, - {3865,3865, 0, 0, 40000, 66,0.000000 }, - {3866,3866, 0, 0, 40000, 26,0.000000 }, - {3867,3867, 0, 0, 40000, 293,0.000000 }, - {3868,3868, 0, 0, 40000, 133,0.000000 }, - {3869,3869, 0, 0, 333, 333,0.000000 }, - {3870,3870, 0, 0, 993, 993,0.000000 }, - {3871,3871, 0, 0, 40000, 280,0.000000 }, - {3872,3872, 0, 0, 1766, 13,0.000000 }, - {3873,3873, 0, 0, 40000, 820,0.000000 }, - {3874,3874, 0, 0, 40000, 286,0.000000 }, - {3875,3875, 0, 0, 40000, 580,0.000000 }, - {3876,3876, 0, 0, 2300, 2300,0.000000 }, - {3877,3877, 0, 0, 40000, 146,0.000000 }, - {3878,3878, 0, 0, 40000, 6,0.000000 }, - {3879,3879, 0, 0, 40000, 66,0.000000 }, - {3880,3880, 0, 0, 40000, 6,0.000000 }, - {3881,3881, 0, 0, 40000, 6,0.000000 }, - {3882,3882, 0, 0, 40000, 126,0.000000 }, - {3883,3883, 0, 0, 40000, 33,0.000000 }, - {3884,3884, 0, 0, 40000, 53,0.000000 }, - {3885,3885, 0, 0, 40000, 93,0.000000 }, - {3886,3886, 0, 0, 40000, 73,0.000000 }, - {3887,3887, 0, 0, 40000, 66,0.000000 }, - {3888,3888, 0, 0, 40000, 86,0.000000 }, - {3889,3889, 0, 0, 40000, 46,0.000000 }, - {3890,3890, 0, 0, 3940, 13,0.000000 }, - {3891,3891, 0, 0, 40000, 33,0.000000 }, - {3892,3892, 0, 0, 40000, 53,0.000000 }, - {3893,3893, 0, 0, 40000, 53,0.000000 }, - {3894,3894, 0, 0, 40000, 73,0.000000 }, - {3895,3895, 0, 0, 40000, 126,0.000000 }, - {3896,3896, 0, 0, 40000, 60,0.000000 }, - {3897,3897, 0, 0, 40000, 106,0.000000 }, - {3898,3898, 0, 0, 40000, 6,0.000000 }, - {3899,3899, 0, 0, 40000, 266,0.000000 }, - {3900,3900, 0, 0, 40000, 53,0.000000 }, - {3901,3901, 0, 0, 40000, 233,0.000000 }, - {3902,3902, 0, 0, 1660, 180,0.000000 }, - {3903,3903, 0, 0, 40000, 566,0.000000 }, - {3904,3904, 0, 0, 40000, 100,0.000000 }, - {3905,3905, 0, 0, 593, 13,0.000000 }, - {3906,3906, 0, 0, 40000, 173,0.000000 }, - {3907,3907, 0, 0, 40000, 53,0.000000 }, - {3908,3908, 0, 0, 40000, 106,0.000000 }, - {3909,3909, 0, 0, 2133, 2133,0.000000 }, - {3910,3910, 0, 0, 40000, 846,0.000000 }, - {3911,3911, 0, 0, 40000, 773,0.000000 }, - {3912,3912, 0, 0, 1066, 1066,0.000000 }, - {3913,3913, 0, 0, 40000, 73,0.000000 }, - {3914,3914, 0, 0, 40000, 86,0.000000 }, - {3915,3915, 0, 0, 40000, 46,0.000000 }, - {3916,3916, 0, 0, 1126, 1126,0.000000 }, - {3917,3917, 0, 0, 40000, 13,0.000000 }, - {3918,3918, 0, 0, 300, 300,0.000000 }, - {3919,3919, 0, 0, 146, 146,0.000000 }, - {3920,3920, 0, 0, 140, 140,0.000000 }, - {3921,3921, 0, 0, 1920, 1920,0.000000 }, - {3922,3922, 0, 0, 40000, 0,0.000000 }, - {3923,3923, 0, 0, 533, 533,0.000000 }, - {3924,3924, 0, 0, 486, 486,0.000000 }, - {3925,3925, 0, 0, 940, 940,0.000000 }, - {3926,3926, 0, 0, 600, 600,0.000000 }, - {3927,3927, 0, 0, 253, 253,0.000000 }, - {3928,3928, 0, 0, 380, 73,0.000000 }, - {3929,3929, 0, 0, 40, 40,0.000000 }, - {3930,3930, 0, 0, 40000, 20,0.000000 }, - {3931,3931, 0, 0, 40000, 13,0.000000 }, - {3932,3932, 0, 0, 4600, 4600,0.000000 }, - {3933,3933, 0, 0, 4820, 4820,0.000000 }, - { 523, 523, 0, 0, 46, 46,0.000000 }, - {3934,3934, 0, 0, 66, 66,0.000000 }, - {3935,3935, 0, 0, 53, 53,0.000000 }, - {3936,3936, 48, 0, 26, 26,0.000000 }, - {3937,3937, 27, 0, 53, 53,0.000000 }, - {3938,3938, 40, 0, 40, 40,0.000000 }, - {3939,3939, 48, 0, 13, 13,0.000000 }, - {3938,3938, 45, 0, 46, 46,0.000000 }, - {3940,3940, 48, 0, 26, 26,0.000000 }, - {3938,3938, 47, 0, 66, 66,0.000000 }, - {3941,3941, 48, 0, 13, 13,0.000000 }, - {3938,3938, 49, 0, 73, 73,0.000000 }, - {3938,3938, 53, 0, 80, 80,0.000000 }, - {3938,3938, 56, 0, 66, 66,0.000000 }, - { 129, 129, 52, 0, 73, 73,0.000000 }, - { 130, 130, 48, 0, 40, 40,0.000000 }, - { 129, 129, 58, 0, 73, 73,0.000000 }, - { 132, 132, 47, 0, 20, 20,0.000000 }, - { 492, 492, 43, 0, 26, 26,0.000000 }, - { 132, 132, 49, 0, 20, 20,0.000000 }, - { 132, 132, 51, 0, 20, 20,0.000000 }, - { 132, 132, 54, 0, 20, 20,0.000000 }, - { 132, 132, 57, 0, 13, 13,0.000000 }, - { 492, 492, 72, 0, 140, 140,0.000000 }, - { 137, 137, 76, 0, 600, 600,0.000000 }, - { 138, 138, 84, 0, 246, 246,0.000000 }, - { 139, 139, 36, 0, 113, 113,0.000000 }, - { 140, 140, 76, 0, 586, 586,0.000000 }, - { 141, 141, 84, 0, 60, 60,0.000000 }, - { 135, 135, 83, 0, 413, 413,0.000000 }, - { 142, 142, 84, 0, 106, 106,0.000000 }, - {3942,3942, 24, 0, 600, 600,0.000000 }, - { 137, 137, 77, 0, 606, 606,0.000000 }, - { 144, 144, 60, 0, 40, 40,0.000000 }, - { 145, 145, 65, 0, 13, 13,0.000000 }, - { 146, 146, 59, 0, 40, 40,0.000000 }, - { 147, 147, 51, 0, 40, 40,0.000000 }, - { 148, 148, 45, 0, 46, 46,0.000000 }, - { 149, 149, 71, 0, 140, 140,0.000000 }, - { 150, 150, 60, 0, 146, 146,0.000000 }, - { 151, 151, 58, 0, 153, 153,0.000000 }, - { 152, 152, 53, 0, 80, 80,0.000000 }, - { 153, 153, 64, 0, 13, 13,0.000000 }, - { 154, 154, 71, 0, 273, 273,0.000000 }, - { 156, 156, 61, 0, 53, 53,0.000000 }, - { 158, 158, 48, 0, 40, 40,0.000000 }, - { 159, 159, 69, 0, 20, 20,0.000000 }, - { 160, 160, 68, 0, 20, 20,0.000000 }, - { 161, 161, 63, 0, 113, 113,0.000000 }, - { 162, 162, 74, 0, 293, 293,0.000000 }, - { 163, 163, 60, 0, 113, 113,0.000000 }, - { 164, 164, 80, 0, 440, 440,0.000000 }, - { 165, 165, 64, 0, 40, 40,0.000000 }, - { 166, 166, 69, 0, 286, 286,0.000000 }, - { 167, 167, 73, 0, 126, 126,0.000000 }, - { 168, 168, 75, 0, 20, 20,0.000000 }, - { 169, 169, 68, 0, 33, 33,0.000000 }, - { 131, 131, 48, 0, 93, 93,0.000000 }, - {3061,3061, 53, 0, 833, 833,0.000000 }, - {3943,3944, 0, 0, 546, 546,0.000000 }, - {3945,3946, 0, 0, 1813, 1813,0.000000 }, - { 174,3947, 0, 0, 1260, 1260,0.000000 }, - {3948,3949, 0, 0, 160, 160,0.000000 }, - { 9,3950, 0, 0, 1100, 1100,0.000000 }, - {3951,3952, 0, 0, 3360, 3360,0.000000 }, - {3953,3954, 0, 0, 1720, 1720,0.000000 }, - { 15,3955, 0, 0, 226, 226,0.000000 }, - {3956,3957, 0, 0, 40000, 6,0.000000 }, - {3958,3959, 0, 0, 40000, 6,0.000000 }, - {3960,3961, 0, 0, 40000, 186,0.000000 }, - {3962,3963, 0, 0, 40000, 6,0.000000 }, - {3964,3965, 0, 0, 146, 146,0.000000 }, - {3966,3965, 0, 0, 146, 146,0.000000 }, - { 31,3967, 0, 0, 3386, 3386,0.000000 }, - {3968,3969, 0, 0, 3520, 3520,0.000000 }, - {3970,3971, 0, 0, 126, 0,0.000000 }, - {3972,3971, 0, 0, 126, 0,0.000000 }, - {3973,3974, 0, 0, 1013, 1013,0.000000 }, - {3975,3976, 0, 0, 3733, 3733,0.000000 }, - {3977,3976, 0, 0, 3733, 3733,0.000000 }, - {3978,3979, 0, 0, 3020, 3020,0.000000 }, - {3980,3981, 0, 0, 686, 686,0.000000 }, - {3982,3983, 0, 0, 40000, 46,0.000000 }, - {3984,3985, 0, 0, 40000, 373,0.000000 }, - { 54,3986, 0, 0, 340, 340,0.000000 }, - {3987,3988, 0, 0, 1213, 6,0.000000 }, - {3989,3990, 0, 0, 40000, 53,0.000000 }, - {3991, 253, 0, 0, 40000, 126,0.000000 }, - {3992,3992, 0, 0, 40, 40,0.000000 }, - {3993,3993, 0, 0, 40000, 53,0.000000 }, - {3994,3995, 0, 0, 40000, 13,0.000000 }, - {3996,3997, 0, 0, 40000, 40,0.000000 }, - {3998,3999, 0, 0, 40000, 13,0.000000 }, - {1503,4000, 0, 0, 40000, 33,0.000000 }, - { 88,4001, 0, 0, 40000, 500,0.000000 }, - {3743,4002, 0, 0, 900, 900,0.000000 }, - { 92,4003, 0, 0, 1720, 13,0.000000 }, - { 93,4004, 0, 0, 1060, 80,0.000000 }, - { 94,4005, 0, 0, 40000, 53,0.000000 }, - { 96,4006, 0, 0, 1913, 533,0.000000 }, - { 103,4007, 0, 0, 1813, 1813,0.000000 }, - { 104,4008, 0, 0, 846, 846,0.000000 }, - { 105,4009, 0, 0, 900, 900,0.000000 }, - { 107,4010, 0, 0, 300, 300,0.000000 }, - { 108,4011, 0, 0, 40000, 6,0.000000 }, - { 110,4012, 0, 0, 40000, 6,0.000000 }, - { 111,4013, 0, 0, 1126, 1126,0.000000 }, - {4014,4015, 0, 0, 140, 140,0.000000 }, - { 115,4016, 0, 0, 146, 146,0.000000 }, - { 118,4017, 0, 0, 2280, 2280,0.000000 }, - { 119,4018, 0, 0, 286, 286,0.000000 }, - { 120,4019, 0, 0, 586, 586,0.000000 }, - { 121,4020, 0, 0, 4426, 4426,0.000000 }, - { 123,4021, 0, 0, 193, 193,0.000000 }, - { 124,4022, 0, 0, 146, 260,0.000000 }, - { 125,4023, 0, 0, 40000, 773,0.000000 }, - {4024,4024, 35, 0, 40, 40,0.000000 }, - {4025,4026, 38, 1, 93, 93,0.000000 }, - {4027,4028, 38, 1, 120, 120,0.000000 }, - {4029,4030, 48, 1, 73, 73,-1.906250 }, - {4031,4031, 51, 0, 26, 26,0.000000 }, - {4032,4033, 48, 1, 293, 293,-1.906250 }, - {4034,4034, 61, 1, 1873, 1873,0.093750 }, - {3369,1557, 70, 0, 906, 906,0.000000 }, - {4035,4036, 79, 1, 293, 293,0.078125 }, - {4037,4037, 62, 0, 1726, 1726,0.000000 }, - {4038,4039, 67, 1, 240, 240,0.078125 }, - {4040,4040, 62, 1, 2040, 2040,0.093750 }, - {4041,4042, 54, 1, 80, 80,0.000000 }, - {4041,4043, 48, 1, 80, 80,0.000000 }, - { 389, 389, 42, 0, 180, 180,0.000000 }, - {4044,4045, 48, 1, 80, 80,0.000000 }, - {4046,4047, 48, 1, 53, 53,0.000000 }, - {4048,4048, 16, 0, 20, 20,0.000000 }, - {4049,4049, 16, 0, 146, 146,0.000000 }, - {4050,4051, 64, 0, 646, 646,0.000000 }, - { 844, 844,244, 0, 13, 13,0.000000 }, - { 855, 855,244, 0, 246, 6,0.000000 }, - { 880, 880,232, 0, 46, 46,0.000000 }, - { 882, 882,220, 0, 5433, 5433,0.000000 }, - { 887, 887, 35, 0, 46, 46,0.000000 }, - { 884, 884, 35, 0, 73, 73,0.000000 }, - { 885, 885, 35, 0, 73, 73,0.000000 }, - { 886, 886, 35, 0, 20, 20,0.000000 }, - { 361, 361, 35, 0, 113, 113,0.000000 }, - { 767, 767, 35, 0, 760, 760,0.000000 }, - { 888, 888, 35, 0, 40, 40,0.000000 }, - {2141,2141, 35, 0, 53, 53,0.000000 }, - { 891, 891, 35, 0, 106, 106,0.000000 }, - {2142,2142, 35, 0, 53, 53,0.000000 }, - {2143,2143, 35, 0, 73, 73,0.000000 }, - {2144,2144, 35, 0, 800, 800,0.000000 }, - {2145,2145, 35, 0, 420, 420,0.000000 }, - { 376, 376, 35, 0, 146, 146,0.000000 }, - { 895, 895, 35, 0, 126, 126,0.000000 }, - {2146,2146, 35, 0, 100, 100,0.000000 }, - { 382, 382, 35, 0, 20, 20,0.000000 }, - {2147,2147, 35, 0, 20, 20,0.000000 }, - { 898, 898, 35, 0, 60, 60,0.000000 }, - { 899, 899, 35, 0, 206, 206,0.000000 }, - { 900, 900, 35, 0, 193, 193,0.000000 }, - { 871, 871, 35, 0, 120, 120,0.000000 }, - { 388, 388, 35, 0, 73, 73,0.000000 }, - { 901, 901, 35, 0, 173, 173,0.000000 }, - { 902, 902, 35, 0, 1006, 1006,0.000000 }, - { 903, 903, 35, 0, 40, 40,0.000000 }, - {3500,3500, 35, 0, 5233, 6,0.000000 }, - {4052,4052, 0, 0, 1400, 1400,0.000000 }, - {4053,4053, 0, 0, 1206, 1206,0.000000 }, - {4054,4054, 0, 0, 40000, 46,0.000000 }, - {4055,4055, 0, 0, 40000, 26,0.000000 }, - {4056,4056, 0, 0, 3600, 3600,0.000000 }, - {4057,4057, 0, 0, 40000, 6,0.000000 }, - {4058,4058, 0, 0, 960, 960,0.000000 }, - {4059,4059, 0, 0, 80, 80,0.000000 }, - {4060,4060, 0, 0, 40000, 20,0.000000 }, - {4061,4061, 0, 0, 40000, 20,0.000000 }, - {4062,4062, 0, 0, 4473, 4473,0.000000 }, - {4063,4063, 0, 0, 380, 6,0.000000 }, - {4064,4064, 0, 0, 40000, 20,0.000000 }, - {4065,4065, 0, 0, 4593, 4593,0.000000 }, - {4066,4066, 0, 0, 40000, 20,0.000000 }, - {4067,4067, 0, 0, 40000, 0,0.000000 }, - {4068,4068, 0, 0, 40, 40,0.000000 }, - {4069,4069, 0, 0, 60, 60,0.000000 }, - {4070,4070, 0, 0, 100, 100,0.000000 }, - {4071,4071, 0, 0, 40000, 40,0.000000 }, - {4072,4072, 0, 0, 126, 126,0.000000 }, - {4073,4073, 0, 0, 40, 40,0.000000 }, - {4074,4074, 0, 0, 40000, 0,0.000000 }, - {4075,4075, 0, 0, 4193, 4193,0.000000 }, - {4076,4076, 0, 0, 806, 0,0.000000 }, - {4077,4077, 0, 0, 526, 526,0.000000 }, - {4078,4078, 0, 0, 40000, 73,0.000000 }, - {4079,4079, 0, 0, 40000, 6,0.000000 }, - {4080,4080, 0, 0, 40000, 153,0.000000 }, - {4081,4081, 0, 0, 40000, 0,0.000000 }, - {4082,4082, 0, 0, 40, 6,0.000000 }, - {4083,4083, 0, 0, 3400, 0,0.000000 }, - {4084,4084, 0, 0, 2280, 0,0.000000 }, - {4085,4085, 0, 0, 40000, 426,0.000000 }, - {4086,4086, 0, 0, 1206, 1206,0.000000 }, - { 127, 127, 36, 0, 20, 20,0.000000 }, - {4087,4087, 36, 0, 6, 6,0.000000 }, - {2030,2030, 36, 0, 93, 93,0.000000 }, - {3782,3782, 48, 0, 6, 6,0.000000 }, - {3783,3783, 36, 0, 33, 33,0.000000 }, - {4088,4088, 48, 0, 246, 246,0.000000 }, - { 132, 132, 69, 0, 13, 13,0.000000 }, - {4088,4088, 52, 0, 360, 360,0.000000 }, - { 152, 152, 48, 0, 86, 86,0.000000 }, - {4088,4088, 55, 0, 493, 493,0.000000 }, - { 139, 139, 57, 0, 93, 93,0.000000 }, - {4088,4088, 58, 0, 560, 560,0.000000 }, - {4088,4088, 60, 0, 580, 580,0.000000 }, - {4089,4089, 62, 0, 840, 840,0.000000 }, - {4088,4088, 63, 0, 626, 626,0.000000 }, - { 134, 134, 70, 0, 140, 140,0.000000 }, - {4090,4090, 70, 0, 286, 286,0.000000 }, - {4091,4091, 53, 0, 613, 613,0.000000 }, - {3516,3516, 48, 0, 40, 40,0.000000 }, - {4092,4092, 84, 0, 420, 420,0.000000 }, - {4093,4093, 43, 0, 160, 160,0.000000 }, - {4094,4094, 56, 0, 326, 326,0.000000 }, - {3791,3791, 24, 0, 140, 140,0.000000 }, - { 134, 134, 65, 0, 160, 160,0.000000 }, - { 146, 146, 48, 0, 40, 40,0.000000 }, - { 146, 146, 54, 0, 40, 40,0.000000 }, - {4095,4095, 42, 0, 46, 46,0.000000 }, - {4095,4095, 39, 0, 46, 46,0.000000 }, - {3816,3816, 52, 0, 106, 106,0.000000 }, - {4096,4096, 52, 0, 200, 200,0.000000 }, - { 158, 158, 60, 0, 33, 33,0.000000 }, - { 158, 158, 66, 0, 33, 33,0.000000 }, - { 158, 158, 59, 0, 33, 33,0.000000 }, - {3538,3538, 91, 0, 273, 273,0.000000 }, - {3547,3547,109, 0, 1780, 1780,0.000000 }, - {4097,4097, 79, 0, 126, 126,0.000000 }, - {4098,4098, 0, 0, 3413, 3413,0.000000 }, - {4099,4100, 0, 1, 1613, 1613,0.031250 }, - {4101,4102, 0, 1, 2146, 2146,0.031250 }, - {4103,4104, 0, 1, 1646, 1646,0.046875 }, - {4105,4106, 0, 1, 1900, 1900,0.156250 }, - {4107,4108, 0, 1, 1473, 1473,0.046875 }, - {4109,4110, 0, 1, 1020, 1020,0.062500 }, - {4111,4112, 0, 1, 2126, 2126,0.000000 }, - {4113,4114, 0, 1, 1740, 1740,0.000000 }, - {4115,4116, 0, 1, 993, 993,0.000025 }, - {4117,4118, 0, 1, 886, 886,0.000000 }, - {4119,4120, 0, 1, 1153, 1153,0.046875 }, - {4121,4122, 0, 1, 1420, 1420,0.000000 }, - {4123,4124, 0, 1, 193, 193,0.000000 }, - {4125,4126, 0, 1, 406, 406,0.000000 }, - {4127,4128, 0, 1, 1400, 1400,0.031250 }, - {4129,4129, 0, 1, 980, 980,0.031250 }, - {4130,4131, 0, 1, 40000, 6,0.156250 }, - {4132,4133, 0, 1, 40, 13,0.078125 }, - {4134,4135, 0, 1, 7180, 13,0.156250 }, - {4136,4137, 0, 1, 40000, 180,0.031250 }, - {4138,4139, 0, 1, 40000, 46,0.062500 }, - {4140,4141, 0, 1, 40000, 46,0.140625 }, - {4142,4143, 0, 1, 40000, 6,0.000000 }, - {4144,4145, 0, 1, 40000, 153,0.109375 }, - {4146,4147, 0, 1, 920, 920,0.000000 }, - {4148,4149, 0, 1, 653, 653,0.000025 }, - {4150,4151, 0, 1, 633, 633,0.000000 }, - {4152,4153, 0, 1, 893, 893,0.046875 }, - {4154,4155, 0, 1, 440, 440,0.000000 }, - {4156,4157, 0, 1, 40000, 60,-1.906250 }, - {4158,4159, 0, 1, 40000, 60,-1.906250 }, - {4160,4161, 0, 1, 2033, 2033,0.234375 }, - {4162,4163, 0, 1, 1900, 1900,0.031250 }, - {4164,4165, 0, 1, 1453, 1453,0.000000 }, - {4166,4167, 0, 1, 2186, 2186,0.000000 }, - {4168,4169, 0, 1, 1933, 1933,0.046875 }, - {4170,4171, 0, 1, 633, 633,0.000000 }, - {4172,4173, 0, 1, 486, 486,0.000000 }, - {4174,4174, 0, 0, 313, 313,0.000000 }, - {4175,4176, 0, 1, 2533, 2533,0.078125 }, - {4177,4178, 0, 1, 2040, 13,0.000000 }, - {4179,4179, 0, 0, 40000, 66,0.000000 }, - {4180,4181, 0, 1, 40000, 60,0.000025 }, - {4182,4182, 0, 0, 40000, 133,0.000000 }, - {4183,4184, 0, 1, 40000, 173,0.078125 }, - {4185,4186, 0, 1, 333, 333,0.109375 }, - {4187,4188, 0, 1, 1813, 1813,0.031250 }, - {4189,4190, 0, 1, 1473, 1473,0.031250 }, - {4191,4192, 0, 1, 40000, 213,0.062500 }, - {4193,4194, 0, 1, 40000, 500,-0.062500 }, - {4195,4195, 0, 1, 40000, 326,0.109375 }, - {4196,4196, 0, 1, 40000, 406,0.109375 }, - {4197,4198, 0, 1, 40000, 280,0.140625 }, - {4199,4200, 0, 1, 40000, 53,0.140625 }, - {4201,4202, 0, 1, 40000, 286,0.156250 }, - {4203,4204, 0, 1, 206, 206,0.125000 }, - {4205,4206, 0, 1, 40000, 26,0.000000 }, - {4207,4208, 0, 1, 40000, 20,0.031250 }, - {4209,4209, 0, 0, 40000, 6,0.000000 }, - {4210,4210, 0, 0, 40000, 20,0.000000 }, - {4211,4212, 0, 1, 40000, 160,0.031250 }, - {4213,4214, 0, 1, 40000, 73,0.062500 }, - {4215,4216, 0, 1, 2526, 2526,0.093750 }, - {4217,4217, 0, 1, 5153, 5153,0.125000 }, - {4218,4219, 0, 1, 40000, 73,0.000000 }, - {4220,4220, 0, 0, 40000, 60,0.000000 }, - {4221,4221, 0, 0, 40000, 0,0.000000 }, - {4222,4222, 0, 0, 40000, 0,0.000000 }, - {4223,4224, 0, 1, 40000, 73,0.000000 }, - {4225,4225, 0, 0, 40000, 33,0.000000 }, - {4226,4226, 0, 0, 40000, 6,0.000000 }, - {4227,4228, 0, 1, 40000, 40,0.000000 }, - {4229,4229, 0, 0, 40000, 0,0.000000 }, - {4230,4230, 0, 0, 40000, 6,0.000000 }, - {4231,4231, 0, 0, 40000, 33,0.000000 }, - {4232,4233, 0, 1, 40000, 53,0.031250 }, - {4234,4235, 0, 1, 40000, 20,0.046875 }, - {4236,4237, 0, 1, 420, 420,0.031250 }, - {4238,4238, 0, 0, 40000, 106,0.000000 }, - {4239,4239, 0, 0, 40000, 6,0.000000 }, - {4240,4241, 0, 1, 40000, 6,0.125000 }, - {4242,4243, 0, 1, 40000, 13,0.109375 }, - {4244,4245, 0, 1, 40000, 53,0.109375 }, - {4246,4247, 0, 1, 226, 6,-0.031250 }, - {4248,4248, 0, 0, 40000, 6,0.000000 }, - {4249,4250, 0, 1, 40000, 133,0.156250 }, - {4251,4252, 0, 1, 4186, 13,0.125000 }, - {4253,4254, 0, 1, 40000, 26,0.031250 }, - {4255,4256, 0, 1, 40000, 660,0.078125 }, - {4257,4258, 0, 1, 846, 66,0.109375 }, - {4259,4260, 0, 1, 1293, 80,0.078125 }, - {4261,4262, 0, 1, 40000, 300,0.140625 }, - {4263,4264, 0, 1, 2040, 2040,0.109375 }, - {4265,4266, 0, 1, 1360, 1360,0.062500 }, - {4267,4268, 0, 1, 40000, 433,0.093750 }, - {4269,4270, 0, 1, 40000, 533,0.109375 }, - {4271,4272, 0, 1, 826, 826,0.093750 }, - {4273,4274, 0, 1, 40000, 926,0.125000 }, - {4275,4275, 0, 1, 886, 886,0.109375 }, - {4276,4277, 0, 1, 2186, 2186,-0.046875 }, - {4278,4279, 0, 1, 1486, 1486,0.125000 }, - {4280,4281, 0, 1, 40000, 393,-0.078125 }, - {4282,4283, 0, 1, 40000, 1166,0.140625 }, - {4284,4285, 0, 1, 360, 360,0.078125 }, - {4286,4287, 0, 1, 1693, 1693,0.031250 }, - {4288,4289, 0, 1, 760, 760,0.000000 }, - {4290,4291, 0, 1, 126, 126,0.031250 }, - {4292,4292, 0, 0, 300, 300,0.000000 }, - {4293,4294, 0, 1, 280, 280,0.000000 }, - {4295,4296, 0, 1, 40000, 26,0.062500 }, - {4297,4297, 0, 0, 40000, 66,0.000000 }, - {4298,4298, 0, 0, 40000, 53,0.000000 }, - {4299,4299, 0, 0, 1940, 1940,0.000000 }, - {4300,4300, 0, 0, 86, 86,0.000000 }, - {4301,4302, 0, 1, 280, 280,0.031250 }, - {4303,4303, 0, 0, 40, 40,0.000000 }, - {4304,4305, 0, 1, 53, 53,0.000000 }, - {4306,4307, 0, 1, 140, 140,0.000000 }, - {4308,4309, 0, 1, 26, 26,0.000000 }, - {4310,4311, 0, 1, 2153, 2153,0.109375 }, - {4312,4312, 0, 0, 293, 293,0.000000 }, - {4313,4314, 0, 1, 993, 26,0.000000 }, - {4315,4316, 0, 1, 5613, 5613,0.000000 }, - {4317,4317, 0, 0, 220, 220,0.000000 }, - {4318,4319, 0, 1, 10306, 526,0.000000 }, - {4320,4321, 0, 1, 1486, 13,0.000000 }, - {4322,4323, 0, 1, 40000, 660,0.000000 }, - {4324,4324, 0, 0, 120, 120,0.000000 }, - {4325,4325, 34, 0, 40, 40,0.000000 }, - {4326,4326, 28, 0, 73, 73,0.000000 }, - {4327,4328, 39, 1, 233, 233,0.000000 }, - {4327,4328, 33, 1, 193, 193,0.000000 }, - {4329,4330, 63, 1, 33, 33,0.000000 }, - {4331,4331, 15, 0, 13, 13,0.000000 }, - {4332,4332, 36, 0, 13, 13,0.000000 }, - {4332,4333, 36, 1, 133, 133,0.406250 }, - {4334,4335, 25, 1, 13, 13,0.000000 }, - {4336,4335, 25, 1, 33, 33,0.000000 }, - {4337,4338, 61, 1, 40, 40,0.000000 }, - {4339,4340, 37, 1, 53, 53,0.000000 }, - {4341,4342, 15, 1, 80, 80,0.000000 }, - {4343,4344, 48, 1, 73, 73,-1.906250 }, - {4345,4346, 19, 1, 120, 120,0.000000 }, - {4347,4347, 48, 0, 53, 53,0.000000 }, - {4348,4349, 15, 1, 33, 33,0.000000 }, - {4350,4351, 12, 1, 33, 33,0.000000 }, - {4352,4353, 11, 1, 33, 33,0.000000 }, - {4354,4353, 8, 1, 40, 40,0.000000 }, - {4355,4356, 60, 1, 246, 246,0.031250 }, - {4357,4357, 70, 0, 340, 340,0.000000 }, - {4358,4359, 80, 1, 106, 106,0.125000 }, - {4360,4360, 58, 0, 73, 73,0.000000 }, - {4361,4362, 31, 1, 313, 313,0.000000 }, - {4363,4363, 61, 0, 253, 253,0.000000 }, - {4364,4365, 41, 1, 100, 100,0.000000 }, - {4366,4367, 35, 1, 160, 160,0.000000 }, - {4368,4369, 29, 1, 40, 40,0.000000 }, - {4370,4371, 41, 1, 166, 166,0.000000 }, - {4370,4371, 37, 1, 160, 160,0.000000 }, - {4372,4373, 54, 1, 80, 80,0.000000 }, - {4372,4374, 48, 1, 80, 80,0.000000 }, - {4375,4376, 77, 1, 53, 53,0.000000 }, - {4377,4378, 72, 1, 46, 46,0.000000 }, - {4379,4379, 40, 0, 140, 140,0.000000 }, - {4380,4380, 38, 0, 73, 73,0.000000 }, - {4381,4381, 36, 0, 533, 533,0.000000 }, - {4382,4383, 60, 1, 26, 26,0.000000 }, - {4383,4384, 60, 1, 26, 26,0.000000 }, - {4385,4385, 73, 0, 60, 60,0.000000 }, - {4386,4387, 68, 1, 40, 40,0.000000 }, - {4388,4389, 18, 1, 60, 60,0.000000 }, - {4390,4391, 18, 1, 106, 106,0.000000 }, - {4392,4392, 90, 0, 80, 80,0.000000 }, - {4393,4393, 90, 0, 306, 306,0.000000 }, - {4394,4395, 64, 1, 233, 233,0.031250 }, - {4396,4397, 80, 1, 140, 140,0.031250 }, - {4398,4399, 64, 1, 606, 606,0.000000 }, - {4400,4400, 67, 0, 20, 20,0.000000 }, - {4401,4402, 50, 1, 53, 53,0.000000 }, - {4403,4403, 36, 0, 66, 66,0.000000 }, - {4404,4404, 0, 0, 40000, 20,0.000000 }, - {4405,4405, 0, 0, 40000, 0,0.000000 }, - {4406,4406, 0, 0, 360, 360,0.000000 }, - {4407,4407, 0, 0, 586, 586,0.000000 }, - {4408,4408, 0, 0, 40000, 0,0.000000 }, - {4409,4409, 0, 0, 40000, 0,0.000000 }, - {4410,4410, 0, 0, 40000, 0,0.000000 }, - {4411,4411, 0, 0, 40000, 6,0.000000 }, - {4412,4412, 0, 0, 40000, 0,0.000000 }, - {4413,4413, 0, 0, 146, 146,0.000000 }, - {4413,4413, 73, 0, 886, 886,0.000000 }, - {4414,4414, 0, 0, 40, 0,0.000000 }, - {4415,4415, 0, 0, 486, 0,0.000000 }, - {4416,4416, 0, 0, 1226, 1226,0.000000 }, - {4417,4417, 0, 0, 1480, 1480,0.000000 }, - {4418,4418, 0, 0, 46, 46,0.000000 }, - {4419,4419, 0, 0, 126, 126,0.000000 }, - {4419,4419, 12, 0, 106, 106,0.000000 }, - {4420,4420, 0, 0, 160, 160,0.000000 }, - {4420,4420, 1, 0, 153, 153,0.000000 }, - {4421,4421, 0, 0, 20, 20,0.000000 }, - {4421,4421, 23, 0, 26, 26,0.000000 }, - {4422,4422, 0, 0, 140, 140,0.000000 }, - {4423,4423, 0, 0, 486, 486,0.000000 }, - {4424,4424, 0, 0, 40000, 13,0.000000 }, - {4425,4425, 0, 0, 40000, 0,0.000000 }, - {4426,4426, 0, 0, 1226, 1226,0.000000 }, - {4427,4427, 0, 0, 766, 766,0.000000 }, - {4428,4428, 0, 0, 93, 93,0.000000 }, - {4429,4429, 0, 2, 40000, 0,0.000000 }, - {4430,4430, 0, 0, 2026, 2026,0.000000 }, - {4431,4431, 0, 0, 2026, 2026,0.000000 }, - {4432,4432, 0, 0, 1920, 1920,0.000000 }, - {4433,4433, 0, 0, 2026, 2026,0.000000 }, - {4434,4434, 0, 0, 3606, 3606,0.000000 }, - {4435,4435, 0, 0, 1226, 1226,0.000000 }, - {4436,4436, 0, 0, 873, 873,0.000000 }, - {4437,4437, 0, 0, 1766, 1766,0.000000 }, - {4438,4438, 0, 0, 4033, 4033,-2.000000 }, - {4439,4439, 0, 0, 3873, 3873,-2.000000 }, - {4440,4440, 0, 0, 300, 300,-2.000000 }, - {4441,4441, 0, 0, 993, 993,0.000000 }, - {4442,4442, 0, 0, 140, 140,0.000000 }, - {4443,4443, 0, 0, 940, 940,0.000000 }, - {4444,4444, 0, 0, 40000, 0,0.000000 }, - {4445,4445, 0, 0, 380, 380,0.000000 }, - {4446,4446, 0, 0, 40000, 0,0.000000 }, - {4447,4447, 0, 0, 40000, 0,0.000000 }, - {4448,4448, 0, 0, 960, 960,0.000000 }, - {4449,4449, 0, 0, 940, 940,0.000000 }, - {4450,4450, 0, 0, 40000, 0,-2.000000 }, - {4451,4451, 0, 0, 40000, 0,-2.000000 }, - {4452,4452, 0, 0, 160, 160,0.000000 }, - {4453,4453, 0, 0, 593, 593,0.000000 }, - {4454,4454, 0, 0, 253, 253,0.000000 }, - {4454,4454, 0, 0, 253, 253,-2.000000 }, - {4455,4455, 0, 0, 1206, 1206,0.000000 }, - {4456,4456, 0, 0, 40000, 0,-2.000000 }, - {4457,4457, 0, 0, 940, 940,-2.000000 }, - {4458,4458, 0, 0, 40000, 46,0.000000 }, - {4459,4459, 0, 0, 40000, 26,0.000000 }, - {4460,4460, 0, 0, 40000, 60,0.000000 }, - {4461,4461, 0, 0, 126, 126,0.000000 }, - {4462,4462, 0, 0, 1580, 1580,0.000000 }, - {4463,4463, 0, 0, 86, 86,0.000000 }, - {4464,4464, 0, 0, 40000, 46,-2.000000 }, - {4465,4465, 0, 0, 40000, 46,-2.000000 }, - {4466,4466, 0, 0, 40000, 240,-2.000000 }, - {4467,4467, 0, 0, 40000, 6,0.000000 }, - {4468,4468, 0, 0, 713, 713,0.000000 }, - {4469,4469, 0, 0, 40000, 73,-2.000000 }, - {4470,4470, 0, 0, 40000, 33,-2.000000 }, - {4471,4471, 0, 0, 40000, 126,-2.000000 }, - {4472,4472, 0, 0, 146, 146,0.000000 }, - {3712,3712, 0, 0, 40000, 126,-2.000000 }, - {4473,4473, 0, 0, 40000, 73,-2.000000 }, - {4474,4474, 0, 0, 40000, 0,0.000000 }, - {4475,4475, 0, 0, 40000, 0,0.000000 }, - {4476,4476, 0, 0, 40000, 0,0.000000 }, - {4477,4477, 0, 0, 40000, 20,-2.000000 }, - {4478,4478, 0, 0, 40000, 13,0.000000 }, - {4479,4479, 0, 0, 40000, 6,-2.000000 }, - {4480,4480, 0, 0, 40000, 13,-2.000000 }, - {4481,4481, 0, 0, 40000, 6,-2.000000 }, - {4482,4482, 0, 0, 40000, 6,0.000000 }, - {4483,4483, 0, 0, 40000, 0,0.000000 }, - {4484,4484, 0, 0, 40000, 20,0.000000 }, - {4485,4485, 0, 0, 40000, 0,0.000000 }, - {4486,4486, 0, 0, 4620, 4620,0.000000 }, - {4487,4487, 0, 0, 40000, 0,0.000000 }, - {4457,4457, 0, 0, 940, 940,0.000000 }, - {4488,4488, 0, 0, 40000, 480,0.000000 }, - {4489,4489, 0, 0, 100, 100,0.000000 }, - {1221,1221, 0, 0, 40000, 53,0.171875 }, - {4490,4490, 0, 0, 160, 160,0.000000 }, - {4491,4491, 0, 0, 2533, 2533,0.000000 }, - {4492,4492, 0, 0, 2506, 2506,0.000000 }, - {4493,4493, 0, 0, 613, 613,0.000000 }, - {4494,4494, 0, 0, 40000, 1120,0.000000 }, - {4495,4495, 0, 0, 40000, 360,0.000000 }, - {4496,4496, 0, 0, 40000, 1053,0.000000 }, - {4497,4497, 0, 0, 40000, 1093,0.000000 }, - {4498,4498, 0, 0, 2260, 2260,0.000000 }, - {4499,4499, 0, 0, 1226, 1226,0.000000 }, - {4500,4500, 0, 0, 993, 993,0.000000 }, - {4501,4501, 0, 0, 40000, 40,0.000000 }, - {4502,4502, 0, 0, 40000, 0,0.000000 }, - {4503,4503, 0, 0, 1206, 1206,0.000000 }, - {4504,4504, 0, 0, 106, 106,-2.000000 }, - {4505,4505, 0, 0, 246, 246,0.000000 }, - {4506,4506, 0, 0, 226, 226,0.000000 }, - {4507,4507, 0, 0, 146, 146,-2.000000 }, - {4508,4508, 0, 0, 40000, 1120,0.000000 }, - {4509,4509, 0, 0, 1866, 33,0.000000 }, - {1261,1261, 0, 0, 40000, 2140,0.000000 }, - {4510,4510, 37, 0, 160, 160,-2.000000 }, - {4511,4511, 48, 0, 13, 13,-2.000000 }, - {4512,4512, 48, 0, 80, 80,-2.000000 }, - {4513,4513, 62, 0, 40, 40,0.000000 }, - {4514,4514, 44, 0, 146, 146,0.000000 }, - {4515,4515, 80, 0, 13, 13,0.000000 }, - {4514,4514, 50, 0, 386, 386,0.000000 }, - {4516,4516, 48, 0, 13, 13,-2.000000 }, - {4514,4514, 55, 0, 246, 246,0.000000 }, - {4517,4517, 61, 0, 160, 160,0.000000 }, - {4514,4514, 58, 0, 280, 280,0.000000 }, - {4514,4514, 63, 0, 313, 313,0.000000 }, - {4518,4518, 71, 0, 300, 300,0.000000 }, - {4514,4514, 72, 0, 253, 253,0.000000 }, - {4519,4519, 70, 0, 626, 626,0.000000 }, - {4518,4518, 88, 0, 293, 293,0.000000 }, - {4520,4520, 76, 0, 606, 606,0.000000 }, - {4521,4521, 84, 0, 80, 80,0.000000 }, - {4518,4518, 68, 0, 286, 286,0.000000 }, - {4522,4522, 72, 0, 33, 33,0.000000 }, - {4523,4523, 28, 0, 253, 253,0.000000 }, - {4519,4519, 81, 0, 440, 440,0.000000 }, - {4524,4524, 58, 0, 66, 66,-2.000000 }, - {4524,4524, 55, 0, 66, 66,-2.000000 }, - {4524,4524, 44, 0, 66, 66,-2.000000 }, - {4524,4524, 49, 0, 66, 66,-2.000000 }, - {4524,4524, 40, 0, 80, 80,-2.000000 }, - {4525,4525, 55, 0, 73, 73,-2.000000 }, - {4525,4525, 48, 0, 80, 80,-2.000000 }, - {4526,4526, 52, 0, 160, 160,0.000000 }, - {4526,4526, 45, 0, 160, 160,0.000000 }, - {4527,4527, 48, 0, 46, 46,-2.000000 }, - {4528,4528, 48, 0, 20, 20,-2.000000 }, - {4529,4529, 48, 0, 153, 153,-2.000000 }, - {4504,4504, 73, 0, 53, 53,-2.000000 }, - {4504,4504, 68, 0, 53, 53,-2.000000 }, - {4504,4504, 63, 0, 73, 73,-2.000000 }, - {4530,4530,108, 0, 220, 220,0.000000 }, - {4531,4531,108, 0, 440, 440,0.000000 }, + { 0, 0, 0, 0, 9006, 133,0 }, + { 1, 1, 0, 0, 9206, 146,0 }, + { 2, 2, 0, 0, 9246, 240,0 }, + { 3, 3, 0, 0, 9440, 140,0 }, + { 4, 4, 0, 0, 8900, 120,0 }, + { 5, 5, 0, 0, 9400, 140,0 }, + { 6, 6, 0, 0, 7460, 380,0 }, + { 7, 7, 0, 0, 9226, 93,0 }, + { 8, 8, 0, 0, 4613, 420,0 }, + { 9, 9, 0, 0, 7286, 4713,0 }, + { 10, 10, 0, 0, 2280, 746,0 }, + { 11, 11, 0, 0, 9233, 240,0 }, + { 12, 12, 0, 0, 346, 153,0 }, + { 13, 13, 0, 0, 633, 233,0 }, + { 14, 14, 0, 0, 4660, 1573,0 }, + { 15, 15, 0, 0, 1166, 400,0 }, + { 16, 16, 0, 0, 40000, 126,0 }, + { 17, 17, 0, 0, 40000, 93,0 }, + { 18, 18, 0, 0, 40000, 93,0 }, + { 19, 19, 0, 0, 40000, 553,0 }, + { 20, 20, 0, 0, 40000, 660,0 }, + { 21, 21, 0, 0, 40000, 73,0 }, + { 22, 22, 0, 0, 40000, 146,0 }, + { 23, 23, 0, 0, 40000, 146,0 }, + { 24, 24, 0, 0, 4026, 100,0 }, + { 25, 25, 0, 0, 14286, 120,0 }, + { 26, 26, 0, 0, 9233, 106,0 }, + { 27, 27, 0, 0, 4480, 100,0 }, + { 28, 28, 0, 0, 40000, 60,0 }, + { 29, 29, 0, 0, 40000, 80,0 }, + { 30, 30, 0, 0, 40000, 80,0 }, + { 31, 31, 0, 0, 18226, 100,0 }, + { 32, 32, 0, 0, 40000, 0,0 }, + { 33, 33, 0, 0, 40000, 80,0 }, + { 34, 34, 0, 0, 40000, 0,0 }, + { 35, 35, 0, 0, 40000, 53,0 }, + { 36, 36, 0, 0, 40000, 0,0 }, + { 37, 37, 0, 0, 40000, 0,0 }, + { 38, 38, 0, 0, 40000, 0,0 }, + { 39, 39, 0, 0, 40000, 160,0 }, + { 40, 40, 0, 0, 40000, 233,0 }, + { 41, 41, 0, 0, 40000, 73,0 }, + { 42, 42, 0, 0, 40000, 233,0 }, + { 43, 43, 0, 0, 40000, 213,0 }, + { 44, 44, 0, 0, 1246, 453,0 }, + { 45, 45, 0, 0, 4580, 786,0 }, + { 46, 46, 0, 0, 6873, 1246,0 }, + { 47, 47, 0, 0, 40000, 100,0 }, + { 48, 48, 0, 0, 40000, 140,0 }, + { 49, 49, 0, 0, 40000, 393,0 }, + { 50, 50, 0, 0, 40000, 406,0 }, + { 51, 51, 0, 0, 40000, 373,0 }, + { 52, 52, 0, 0, 40000, 0,0 }, + { 53, 53, 0, 0, 40000, 360,0 }, + { 54, 54, 0, 0, 1060, 380,0 }, + { 55, 55, 0, 0, 40000, 80,0 }, + { 56, 56, 0, 0, 40000, 73,0 }, + { 57, 57, 0, 0, 40000, 66,0 }, + { 58, 58, 0, 0, 40000, 60,0 }, + { 59, 59, 0, 0, 40000, 73,0 }, + { 60, 60, 0, 0, 40000, 66,0 }, + { 61, 61, 0, 0, 40000, 86,0 }, + { 62, 62, 0, 0, 40000, 66,0 }, + { 63, 63, 0, 0, 40000, 73,0 }, + { 64, 64, 0, 0, 40000, 80,0 }, + { 65, 65, 0, 0, 40000, 80,0 }, + { 66, 66, 0, 0, 40000, 73,0 }, + { 67, 67, 0, 0, 40000, 73,0 }, + { 68, 68, 0, 0, 40000, 53,0 }, + { 69, 69, 0, 0, 40000, 73,0 }, + { 70, 70, 0, 0, 40000, 126,0 }, + { 71, 71, 0, 0, 40000, 73,0 }, + { 72, 72, 0, 0, 40000, 73,0 }, + { 73, 73, 0, 0, 40000, 73,0 }, + { 74, 74, 0, 0, 40000, 66,0 }, + { 75, 75, 0, 0, 40000, 153,0 }, + { 76, 76, 0, 0, 40000, 153,0 }, + { 77, 77, 0, 0, 40000, 146,0 }, + { 78, 78, 0, 0, 40000, 146,0 }, + { 79, 79, 0, 0, 40000, 66,0 }, + { 80, 80, 0, 0, 40000, 60,0 }, + { 81, 81, 0, 0, 40000, 86,0 }, + { 82, 82, 0, 0, 40000, 73,0 }, + { 83, 83, 0, 0, 40000, 66,0 }, + { 84, 84, 0, 0, 40000, 153,0 }, + { 85, 85, 0, 0, 40000, 233,0 }, + { 86, 86, 0, 0, 40000, 80,0 }, + { 87, 87, 0, 0, 40000, 400,0 }, + { 88, 88, 0, 0, 40000, 1373,0 }, + { 89, 89, 0, 0, 40000, 193,0 }, + { 90, 90, 0, 0, 40000, 1273,0 }, + { 91, 91, 0, 0, 40000, 186,0 }, + { 92, 92, 0, 0, 40000, 86,0 }, + { 93, 93, 0, 0, 40000, 286,0 }, + { 94, 94, 0, 0, 40000, 140,0 }, + { 95, 95, 0, 0, 7440, 2473,0 }, + { 96, 96, 0, 0, 40000, 1220,0 }, + { 97, 97, 0, 0, 4946, 2713,0 }, + { 98, 98, 0, 0, 40000, 160,0 }, + { 99, 99, 0, 0, 8966, 406,0 }, + { 100, 100, 0, 0, 40000, 1353,0 }, + { 101, 101, 0, 0, 40000, 1306,0 }, + { 102, 102, 0, 0, 40000, 933,0 }, + { 103, 103, 0, 0, 9086, 226,0 }, + { 104, 104, 0, 0, 7233, 326,0 }, + { 105, 105, 0, 0, 7286, 200,0 }, + { 106, 106, 0, 0, 14180, 4406,0 }, + { 107, 107, 0, 0, 1180, 406,0 }, + { 108, 108, 0, 0, 40000, 66,0 }, + { 109, 109, 0, 0, 40000, 213,0 }, + { 110, 110, 0, 0, 40000, 73,0 }, + { 111, 111, 0, 0, 4606, 413,0 }, + { 112, 112, 0, 0, 613, 240,0 }, + { 113, 113, 0, 0, 1166, 400,0 }, + { 114, 114, 0, 0, 200, 353,0 }, + { 115, 115, 0, 0, 4553, 1480,0 }, + { 116, 116, 0, 0, 3740, 1260,0 }, + { 117, 117, 0, 0, 7240, 2300,0 }, + { 118, 118, 0, 0, 3020, 73,0 }, + { 119, 119, 0, 0, 1626, 800,0 }, + { 120, 120, 0, 0, 2466, 620,0 }, + { 121, 121, 0, 0, 12053, 3160,0 }, + { 122, 122, 0, 0, 466, 120,0 }, + { 123, 123, 0, 0, 1000, 320,0 }, + { 124, 124, 0, 0, 380, 60,0 }, + { 125, 125, 0, 0, 40000, 200,0 }, + { 126, 126, 0, 0, 560, 86,0 }, + { 127, 127, 35, 0, 386, 160,0 }, + { 128, 128, 52, 0, 126, 26,0 }, + { 129, 129, 48, 0, 286, 126,0 }, + { 130, 130, 58, 0, 173, 93,0 }, + { 129, 129, 60, 0, 286, 126,0 }, + { 131, 131, 47, 0, 520, 200,0 }, + { 132, 132, 43, 0, 173, 93,0 }, + { 131, 131, 49, 0, 520, 200,0 }, + { 133, 133, 43, 0, 160, 80,0 }, + { 131, 131, 51, 0, 526, 206,0 }, + { 134, 134, 43, 0, 1860, 653,0 }, + { 131, 131, 54, 0, 520, 200,0 }, + { 131, 131, 57, 0, 520, 200,0 }, + { 135, 135, 72, 0, 1860, 633,0 }, + { 131, 131, 60, 0, 506, 200,0 }, + { 136, 136, 76, 0, 1566, 546,0 }, + { 137, 137, 84, 0, 1340, 466,0 }, + { 138, 138, 36, 0, 1220, 433,0 }, + { 139, 139, 65, 0, 293, 133,0 }, + { 140, 140, 84, 0, 1333, 460,0 }, + { 141, 141, 83, 0, 220, 113,0 }, + { 135, 135, 84, 0, 1366, 473,0 }, + { 142, 142, 24, 0, 1893, 633,0 }, + { 136, 136, 77, 0, 1586, 553,0 }, + { 143, 143, 60, 0, 173, 93,0 }, + { 144, 144, 65, 0, 213, 126,0 }, + { 145, 145, 59, 0, 173, 0,0 }, + { 146, 146, 51, 0, 173, 100,0 }, + { 147, 147, 45, 0, 260, 206,0 }, + { 148, 148, 71, 0, 433, 180,0 }, + { 149, 149, 60, 0, 280, 26,0 }, + { 150, 150, 58, 0, 500, 186,0 }, + { 151, 151, 53, 0, 513, 200,0 }, + { 152, 152, 64, 0, 220, 86,0 }, + { 153, 153, 71, 0, 106, 46,0 }, + { 154, 154, 61, 0, 993, 340,0 }, + { 155, 155, 61, 0, 1906, 640,0 }, + { 156, 156, 44, 0, 206, 86,0 }, + { 157, 157, 40, 0, 586, 140,0 }, + { 158, 158, 69, 0, 126, 140,0 }, + { 159, 159, 68, 0, 126, 140,0 }, + { 160, 160, 63, 0, 146, 166,0 }, + { 161, 161, 74, 0, 280, 100,0 }, + { 162, 162, 60, 0, 1026, 320,0 }, + { 163, 163, 80, 0, 226, 100,0 }, + { 164, 164, 64, 0, 2713, 913,0 }, + { 165, 165, 72, 0, 120, 66,0 }, + { 166, 166, 73, 0, 386, 80,0 }, + { 167, 167, 70, 0, 553, 306,0 }, + { 168, 168, 68, 0, 126, 140,0 }, + { 169, 169, 48, 0, 386, 373,0 }, + { 131, 131, 53, 0, 520, 206,0 }, + { 170, 170, 0, 0, 40000, 0,0 }, + { 171, 171, 0, 0, 40000, 73,0 }, + { 172, 173, 0, 4, 5886, 100,0 }, + { 174, 175, 0, 4, 6913, 0,0 }, + { 176, 177, 0, 4, 4873, 0,0 }, + { 178, 178, 0, 0, 40000, 0,0 }, + { 179, 180, 0, 4, 4653, 433,0 }, + { 181, 181, 0, 0, 2280, 746,0 }, + { 182, 182, 0, 0, 40000, 0,0 }, + { 183, 184, 0, 4, 626, 0,0 }, + { 185, 186, 0, 4, 4653, 1546,0 }, + { 187, 187, 0, 0, 1166, 400,0 }, + { 188, 189, 0, 4, 40000, 60,0 }, + { 190, 191, 0, 4, 40000, 60,0 }, + { 192, 193, 0, 4, 40000, 73,0 }, + { 194, 194, 0, 0, 40000, 73,0 }, + { 195, 196, 0, 4, 40000, 66,0 }, + { 197, 198, 0, 4, 40000, 86,0 }, + { 199, 200, 0, 4, 40000, 66,0 }, + { 201, 202, 0, 4, 3713, 100,0 }, + { 203, 204, 0, 4, 14753, 126,0 }, + { 205, 206, 0, 4, 9286, 146,0 }, + { 207, 208, 0, 4, 14713, 126,0 }, + { 209, 210, 0, 4, 4653, 0,0 }, + { 211, 212, 0, 4, 40000, 66,0 }, + { 213, 213, 0, 0, 40000, 73,0 }, + { 214, 215, 0, 4, 626, 0,0 }, + { 216, 217, 0, 4, 4066, 100,0 }, + { 218, 219, 0, 4, 14586, 193,0 }, + { 220, 221, 0, 4, 2813, 106,0 }, + { 222, 223, 0, 4, 500, 0,0 }, + { 224, 224, 0, 0, 40000, 0,0 }, + { 225, 226, 0, 4, 7993, 93,0 }, + { 227, 227, 0, 0, 40000, 0,0 }, + { 228, 228, 0, 0, 40000, 133,0 }, + { 229, 230, 0, 4, 720, 213,0 }, + { 231, 232, 0, 4, 40000, 146,0 }, + { 233, 234, 0, 4, 40000, 0,0 }, + { 235, 236, 0, 4, 1000, 340,0 }, + { 235, 237, 0, 4, 3280, 1120,0 }, + { 46, 238, 0, 4, 6920, 0,0 }, + { 239, 240, 0, 4, 40000, 140,0 }, + { 241, 242, 0, 4, 40000, 146,0 }, + { 243, 243, 0, 0, 40000, 100,0 }, + { 244, 244, 0, 0, 40000, 60,0 }, + { 245, 245, 0, 0, 40000, 73,0 }, + { 246, 247, 0, 4, 720, 106,0 }, + { 248, 249, 0, 4, 40000, 126,0 }, + { 250, 250, 0, 0, 40000, 0,0 }, + { 251, 251, 0, 0, 40000, 126,0 }, + { 252, 253, 0, 4, 40000, 66,0 }, + { 254, 255, 0, 4, 40000, 93,0 }, + { 256, 257, 0, 4, 40000, 73,0 }, + { 258, 259, 0, 4, 40000, 86,0 }, + { 260, 261, 0, 4, 40000, 93,0 }, + { 262, 263, 0, 4, 40000, 80,0 }, + { 264, 265, 0, 4, 40000, 200,0 }, + { 266, 267, 0, 4, 40000, 73,0 }, + { 268, 269, 0, 4, 40000, 80,0 }, + { 270, 271, 0, 4, 40000, 73,0 }, + { 272, 273, 0, 4, 40000, 126,0 }, + { 274, 275, 0, 4, 40000, 100,0 }, + { 276, 276, 0, 0, 40000, 113,0 }, + { 277, 278, 0, 4, 40000, 186,0 }, + { 279, 280, 0, 4, 40000, 160,0 }, + { 281, 282, 0, 4, 40000, 206,0 }, + { 283, 283, 0, 0, 40000, 80,0 }, + { 284, 285, 0, 4, 40000, 73,0 }, + { 286, 287, 0, 4, 40000, 73,0 }, + { 288, 288, 0, 0, 40000, 93,0 }, + { 289, 290, 0, 4, 40000, 66,0 }, + { 291, 292, 0, 4, 40000, 153,0 }, + { 293, 294, 0, 4, 40000, 153,0 }, + { 295, 296, 0, 4, 40000, 320,0 }, + { 88, 297, 0, 4, 40000, 1280,0 }, + { 298, 299, 0, 4, 40000, 266,0 }, + { 300, 301, 0, 4, 40000, 1180,0 }, + { 302, 302, 0, 0, 40000, 286,0 }, + { 303, 303, 0, 0, 40000, 140,0 }, + { 304, 304, 0, 0, 13246, 2473,0 }, + { 305, 306, 0, 4, 40000, 1073,0 }, + { 307, 307, 0, 0, 9233, 240,0 }, + { 308, 308, 0, 0, 1186, 406,0 }, + { 309, 309, 0, 0, 40000, 1306,0 }, + { 310, 310, 0, 0, 40000, 933,0 }, + { 311, 312, 0, 4, 9146, 240,0 }, + { 313, 314, 0, 4, 7306, 326,0 }, + { 315, 316, 0, 4, 3586, 326,0 }, + { 317, 318, 0, 4, 7180, 0,0 }, + { 107, 319, 0, 4, 1180, 406,0 }, + { 108, 320, 0, 4, 40000, 66,0 }, + { 109, 321, 0, 4, 720, 213,0 }, + { 322, 323, 0, 4, 40000, 73,0 }, + { 324, 325, 0, 4, 613, 246,0 }, + { 326, 327, 0, 4, 1213, 386,0 }, + { 328, 328, 0, 0, 173, 106,0 }, + { 329, 329, 0, 0, 966, 333,0 }, + { 330, 331, 0, 4, 1906, 320,0 }, + { 332, 332, 0, 0, 3120, 73,0 }, + { 333, 333, 0, 0, 226, 73,0 }, + { 334, 334, 0, 0, 6600, 806,0 }, + { 335, 335, 0, 0, 273, 60,0 }, + { 336, 336, 0, 0, 12053, 660,0 }, + { 337, 337, 0, 0, 40000, 240,0 }, + { 338, 339, 0, 6, 6, 0,0 }, + { 340, 341, 0, 4, 560, 0,0 }, + { 342, 342, 35, 0, 40000, 0,0 }, + { 343, 343, 0, 0, 180, 100,0 }, + { 344, 344, 35, 0, 340, 146,0 }, + { 345, 345, 35, 0, 213, 33,0 }, + { 346, 346, 50, 0, 306, 20,0 }, + { 347, 347, 18, 0, 420, 146,0 }, + { 348, 348, 72, 0, 173, 86,0 }, + { 349, 349, 74, 0, 160, 93,0 }, + { 350, 350, 35, 0, 380, 146,0 }, + { 351, 351, 16, 0, 1206, 420,0 }, + { 352, 352, 0, 2, 6, 0,0 }, + { 353, 353, 38, 0, 200, 106,0 }, + { 354, 354, 38, 0, 346, 146,0 }, + { 355, 355, 31, 0, 406, 20,0 }, + { 355, 355, 35, 0, 406, 66,0 }, + { 355, 355, 38, 0, 406, 66,0 }, + { 355, 355, 41, 0, 406, 66,0 }, + { 355, 355, 45, 0, 306, 73,0 }, + { 355, 355, 50, 0, 306, 73,0 }, + { 356, 356, 36, 0, 1373, 493,0 }, + { 357, 357, 36, 0, 146, 33,0 }, + { 358, 358, 48, 0, 213, 86,0 }, + { 358, 358, 36, 0, 246, 86,0 }, + { 359, 359, 36, 0, 113, 0,0 }, + { 360, 360, 0, 0, 133, 40,0 }, + { 361, 361, 61, 0, 180, 26,0 }, + { 362, 362, 96, 0, 706, 266,0 }, + { 363, 363, 38, 0, 520, 193,0 }, + { 127, 127, 16, 0, 620, 233,0 }, + { 364, 365, 18, 4, 200, 0,0 }, + { 366, 366, 30, 0, 406, 246,0 }, + { 367, 368, 35, 4, 200, 0,0 }, + { 129, 129, 0, 0, 353, 153,0 }, + { 369, 369, 0, 0, 213, 13,0 }, + { 370, 370, 88, 0, 333, 113,0 }, + { 371, 371, 88, 0, 140, 73,0 }, + { 372, 372, 79, 0, 2540, 1040,0 }, + { 135, 135, 14, 0, 9213, 3066,0 }, + { 373, 373, 46, 0, 1093, 60,0 }, + { 374, 375,129, 4, 1200, 433,0 }, + { 376, 376, 58, 0, 1600, 726,0 }, + { 377, 377,164, 0, 526, 820,0 }, + { 378, 378,142, 0, 9153, 3073,0 }, + { 379, 379, 9, 0, 200, 100,0 }, + { 380, 381, 35, 4, 2353, 813,0 }, + { 382, 382, 28, 0, 1060, 120,0 }, + { 383, 383, 46, 0, 953, 20,0 }, + { 384, 384, 60, 0, 440, 160,0 }, + { 384, 384, 54, 0, 513, 180,0 }, + { 385, 385, 72, 0, 253, 120,0 }, + { 385, 385, 67, 0, 253, 113,0 }, + { 385, 385, 60, 0, 253, 106,0 }, + { 386, 386, 1, 0, 966, 613,0 }, + { 387, 387, 77, 0, 340, 86,0 }, + { 387, 387, 72, 0, 340, 86,0 }, + { 388, 388, 90, 0, 213, 86,0 }, + { 389, 389, 39, 0, 266, 73,0 }, + { 390, 390, 36, 0, 593, 73,0 }, + { 391, 392, 35, 4, 173, 46,0 }, + { 391, 393, 35, 4, 460, 66,0 }, + { 394, 394, 60, 0, 173, 20,0 }, + { 328, 328, 7, 0, 173, 0,0 }, + { 395, 395, 90, 0, 193, 20,0 }, + { 396, 396, 90, 0, 793, 40,0 }, + { 397, 397, 35, 0, 253, 86,0 }, + { 398, 399, 5, 4, 1913, 226,0 }, + { 400, 400,103, 0, 713, 273,0 }, + { 401, 401, 3, 0, 100, 0,0 }, + { 169, 169, 1, 0, 466, 413,0 }, + { 131, 131, 0, 0, 613, 226,0 }, + { 402, 402, 36, 0, 273, 53,0 }, + { 403, 403, 60, 0, 40000, 73,0 }, + { 404, 404, 37, 0, 1193, 426,0 }, + { 405, 405, 36, 0, 406, 20,0 }, + { 406, 406, 32, 0, 146, 73,0 }, + { 407, 407, 50, 0, 40000, 0,0 }, + { 408, 408, 50, 0, 793, 346,0 }, + { 409, 409, 83, 0, 120, 13,0 }, + { 410, 410, 72, 0, 433, 0,0 }, + { 148, 148, 59, 0, 513, 200,0 }, + { 411, 411, 64, 0, 173, 93,0 }, + { 411, 411, 60, 0, 173, 93,0 }, + { 412, 412, 72, 0, 160, 93,0 }, + { 412, 412, 62, 0, 173, 93,0 }, + { 413, 413, 83, 0, 773, 60,0 }, + { 414, 414, 0, 0, 40000, 80,0 }, + { 415, 415, 0, 0, 40000, 0,0 }, + { 416, 416, 0, 0, 40000, 73,0 }, + { 417, 417, 0, 0, 40000, 86,0 }, + { 418, 418, 0, 0, 40000, 0,0 }, + { 419, 419, 0, 0, 3440, 100,0 }, + { 420, 420, 0, 0, 3913, 420,0 }, + { 421, 421, 0, 0, 13620, 4640,0 }, + { 422, 422, 0, 0, 9233, 240,0 }, + { 423, 423, 0, 0, 633, 233,0 }, + { 424, 424, 0, 0, 4660, 1573,0 }, + { 425, 425, 0, 0, 4480, 1413,0 }, + { 426, 426, 0, 0, 40000, 0,0 }, + { 427, 427, 0, 0, 40000, 86,0 }, + { 428, 428, 60, 2, 6, 0,0 }, + { 429, 429, 73, 0, 593, 86,0 }, + { 429, 429, 74, 0, 593, 86,0 }, + { 429, 429, 80, 0, 593, 86,0 }, + { 429, 429, 84, 0, 593, 86,0 }, + { 429, 429, 92, 0, 520, 86,0 }, + { 430, 430, 81, 0, 786, 80,0 }, + { 430, 430, 83, 0, 786, 80,0 }, + { 430, 430, 95, 0, 680, 80,0 }, + { 431, 431, 35, 0, 593, 140,0 }, + { 432, 432, 60, 0, 213, 133,0 }, + { 357, 357, 59, 0, 113, 0,0 }, + { 432, 432, 44, 0, 213, 133,0 }, + { 433, 433, 41, 0, 713, 273,0 }, + { 434, 434, 97, 0, 113, 46,0 }, + { 433, 433, 44, 0, 513, 206,0 }, + { 433, 433, 48, 0, 506, 200,0 }, + { 435, 435, 96, 0, 700, 86,0 }, + { 433, 433, 51, 0, 520, 200,0 }, + { 433, 433, 54, 0, 513, 206,0 }, + { 436, 436, 40, 0, 1506, 793,0 }, + { 433, 433, 57, 0, 380, 160,0 }, + { 437, 437, 58, 0, 1600, 726,0 }, + { 438, 438, 97, 0, 233, 106,0 }, + { 439, 439, 50, 0, 186, 93,0 }, + { 437, 437, 60, 0, 1573, 713,0 }, + { 440, 440, 53, 0, 180, 73,0 }, + { 441, 441, 46, 0, 173, 126,0 }, + { 440, 440, 57, 0, 180, 40,0 }, + { 442, 442, 42, 0, 640, 240,0 }, + { 442, 442, 37, 0, 633, 233,0 }, + { 443, 443, 41, 0, 626, 240,0 }, + { 443, 443, 37, 0, 620, 233,0 }, + { 444, 444, 77, 0, 173, 40,0 }, + { 444, 444, 72, 0, 173, 40,0 }, + { 445, 445, 70, 0, 233, 100,0 }, + { 445, 445, 90, 0, 233, 93,0 }, + { 446, 446, 46, 0, 133, 73,0 }, + { 447, 447, 48, 0, 333, 73,0 }, + { 448, 448, 85, 0, 106, 0,0 }, + { 449, 449, 66, 0, 180, 26,0 }, + { 449, 449, 61, 0, 180, 26,0 }, + { 450, 450, 41, 0, 200, 66,0 }, + { 451, 451, 41, 0, 253, 66,0 }, + { 452, 452, 81, 0, 253, 26,0 }, + { 400, 400, 81, 0, 820, 306,0 }, + { 400, 400, 76, 0, 813, 300,0 }, + { 359, 359, 60, 0, 100, 0,0 }, + { 453, 453, 53, 0, 40000, 0,0 }, + { 454, 454, 0, 2, 6, 0,0 }, + { 455, 455, 0, 0, 200, 20,0 }, + { 456, 456, 0, 0, 4480, 100,0 }, + { 457, 457, 0, 0, 1180, 406,0 }, + { 458, 458, 0, 0, 40000, 86,0 }, + { 459, 459, 0, 0, 40000, 73,0 }, + { 460, 460, 0, 0, 3700, 66,0 }, + { 461, 461, 0, 0, 40000, 0,0 }, + { 462, 462, 0, 0, 6746, 2606,0 }, + { 463, 463, 0, 0, 40000, 213,0 }, + { 464, 464, 0, 0, 40000, 66,0 }, + { 465, 465, 0, 0, 40000, 100,0 }, + { 466, 466, 0, 0, 40000, 100,0 }, + { 467, 467, 0, 0, 5840, 806,0 }, + { 468, 468, 0, 0, 40000, 0,0 }, + { 469, 469, 0, 0, 40000, 0,0 }, + { 470, 470, 0, 0, 40000, 73,0 }, + { 471, 471, 0, 0, 40000, 133,0 }, + { 472, 472, 0, 0, 3320, 800,0 }, + { 473, 473, 0, 0, 40000, 173,0 }, + { 474, 474, 0, 0, 40000, 193,0 }, + { 475, 475, 0, 0, 2373, 800,0 }, + { 476, 476, 0, 0, 40000, 4986,0 }, + { 477, 477, 0, 0, 1180, 413,0 }, + { 478, 478, 0, 0, 3673, 1200,0 }, + { 479, 479, 0, 0, 973, 800,0 }, + { 480, 480, 0, 0, 7233, 2286,0 }, + { 481, 481, 0, 0, 40000, 73,0 }, + { 482, 482, 0, 0, 2526, 73,0 }, + { 483, 483, 0, 0, 393, 126,0 }, + { 484, 484, 0, 0, 40000, 200,0 }, + { 485, 485, 0, 0, 40000, 546,0 }, + { 486, 486, 0, 0, 1186, 413,0 }, + { 487, 487, 0, 0, 14166, 320,0 }, + { 488, 488, 0, 0, 8326, 646,0 }, + { 489, 489, 0, 0, 513, 206,0 }, + { 490, 490, 0, 0, 40000, 93,0 }, + { 491, 491, 50, 0, 1406, 353,0 }, + { 492, 492, 37, 0, 1040, 400,0 }, + { 493, 493, 39, 0, 406, 73,0 }, + { 494, 494, 39, 0, 3746, 860,0 }, + { 495, 495, 86, 0, 2133, 173,0 }, + { 496, 496, 43, 0, 140, 66,0 }, + { 127, 127, 24, 0, 513, 206,0 }, + { 127, 127, 29, 0, 520, 206,0 }, + { 497, 497, 50, 0, 340, 20,0 }, + { 498, 498, 30, 0, 5306, 1266,0 }, + { 498, 498, 33, 0, 3773, 886,0 }, + { 498, 498, 38, 0, 3746, 860,0 }, + { 498, 498, 42, 0, 3793, 906,0 }, + { 499, 499, 24, 0, 266, 0,0 }, + { 499, 499, 27, 0, 260, 153,0 }, + { 499, 499, 29, 0, 260, 153,0 }, + { 499, 499, 32, 0, 260, 153,0 }, + { 500, 500, 32, 0, 106, 0,0 }, + { 501, 501, 53, 0, 373, 186,0 }, + { 501, 501, 57, 0, 380, 193,0 }, + { 502, 502, 60, 0, 286, 133,0 }, + { 503, 503, 55, 0, 460, 126,0 }, + { 486, 486, 85, 0, 813, 293,0 }, + { 504, 504, 90, 0, 1580, 546,0 }, + { 505, 505, 84, 0, 246, 120,0 }, + { 506, 506, 48, 0, 826, 646,0 }, + { 507, 507, 48, 0, 266, 213,0 }, + { 132, 132, 72, 0, 126, 66,0 }, + { 508, 508, 72, 0, 106, 0,0 }, + { 509, 509, 72, 0, 100, 0,0 }, + { 510, 510, 63, 0, 1860, 633,0 }, + { 510, 510, 65, 0, 1853, 633,0 }, + { 511, 511, 79, 0, 1573, 553,0 }, + { 512, 512, 38, 0, 520, 793,0 }, + { 513, 513, 94, 0, 380, 160,0 }, + { 514, 514, 87, 0, 433, 306,0 }, + { 514, 514, 94, 0, 380, 273,0 }, + { 515, 515, 80, 0, 546, 273,0 }, + { 516, 516, 47, 0, 506, 200,0 }, + { 517, 517, 61, 0, 286, 133,0 }, + { 517, 517, 68, 0, 246, 120,0 }, + { 518, 518, 61, 0, 513, 206,0 }, + { 518, 518, 68, 0, 433, 180,0 }, + { 499, 499, 60, 0, 220, 133,0 }, + { 519, 519, 60, 0, 153, 46,0 }, + { 520, 520, 36, 0, 200, 20,0 }, + { 520, 520, 60, 0, 173, 20,0 }, + { 521, 521, 60, 0, 173, 20,0 }, + { 522, 522, 68, 0, 126, 26,0 }, + { 523, 523, 71, 0, 160, 186,0 }, + { 523, 523, 72, 0, 160, 186,0 }, + { 524, 524,101, 0, 966, 353,0 }, + { 525, 525, 36, 0, 3333, 480,0 }, + { 526, 526, 25, 0, 40000, 2293,0 }, + { 527, 527, 37, 0, 2106, 426,0 }, + { 528, 528, 36, 0, 720, 266,0 }, + { 528, 528, 41, 0, 713, 266,0 }, + { 529, 529, 84, 0, 173, 60,0 }, + { 530, 530, 54, 0, 40000, 0,0 }, + { 481, 481, 48, 0, 40000, 73,0 }, + { 531, 531, 0, 0, 10060, 1266,0 }, + { 532, 532, 0, 0, 4600, 606,0 }, + { 533, 533, 0, 0, 40000, 253,0 }, + { 534, 534, 0, 0, 40000, 73,0 }, + { 535, 535, 0, 0, 40000, 66,0 }, + { 536, 536, 0, 0, 40000, 80,0 }, + { 537, 537, 0, 0, 9413, 1393,0 }, + { 538, 538, 0, 0, 9000, 66,0 }, + { 539, 539, 0, 0, 40000, 0,0 }, + { 540, 540, 0, 0, 40000, 80,0 }, + { 541, 541, 0, 0, 40000, 120,0 }, + { 542, 542, 0, 0, 253, 73,0 }, + { 543, 543, 0, 0, 40000, 73,0 }, + { 544, 544, 0, 0, 18280, 800,0 }, + { 545, 545, 0, 0, 40000, 1133,0 }, + { 546, 546, 0, 0, 40000, 1226,0 }, + { 547, 547, 0, 0, 40000, 153,0 }, + { 135, 135, 49, 0, 3633, 1186,0 }, + { 548, 548, 35, 0, 2193, 80,0 }, + { 549, 549, 41, 0, 73, 0,0 }, + { 366, 366, 38, 0, 406, 246,0 }, + { 550, 550, 39, 0, 106, 20,0 }, + { 551, 551, 49, 0, 200, 133,0 }, + { 408, 408, 59, 0, 780, 326,0 }, + { 552, 552, 24, 0, 40000, 0,0 }, + { 552, 552, 27, 0, 40000, 0,0 }, + { 552, 552, 29, 0, 40000, 0,0 }, + { 552, 552, 32, 0, 40000, 0,0 }, + { 553, 553, 84, 0, 200, 33,0 }, + { 512, 512, 79, 0, 346, 460,0 }, + { 554, 554, 61, 0, 400, 126,0 }, + { 554, 554, 68, 0, 353, 120,0 }, + { 555, 555, 36, 0, 146, 86,0 }, + { 555, 555, 60, 0, 113, 0,0 }, + { 556, 556, 36, 0, 273, 53,0 }, + { 115, 115, 37, 0, 4580, 1513,0 }, + { 557, 557, 0, 0, 3806, 73,0 }, + { 558, 558, 0, 0, 40000, 0,0 }, + { 559, 559, 0, 0, 40000, 66,0 }, + { 560, 560, 0, 0, 5886, 133,0 }, + { 561, 561, 0, 0, 253, 26,0 }, + { 562, 562, 0, 0, 3246, 753,0 }, + { 563, 563, 0, 0, 40000, 100,0 }, + { 564, 564, 0, 0, 1620, 366,0 }, + { 565, 565, 0, 0, 40000, 0,0 }, + { 566, 566, 0, 0, 40000, 0,0 }, + { 567, 567, 0, 0, 40000, 0,0 }, + { 568, 568, 0, 0, 40000, 80,0 }, + { 569, 569, 0, 0, 760, 340,0 }, + { 570, 570, 0, 0, 40000, 0,0 }, + { 571, 571, 0, 0, 40000, 0,0 }, + { 572, 572, 0, 0, 40000, 0,0 }, + { 356, 356, 0, 0, 1893, 646,0 }, + { 573, 573, 0, 0, 40000, 93,0 }, + { 574, 574, 0, 0, 40000, 93,0 }, + { 575, 575, 0, 0, 40000, 200,0 }, + { 576, 576, 0, 0, 40000, 200,0 }, + { 577, 577, 0, 0, 40000, 126,0 }, + { 578, 578, 0, 0, 40000, 353,0 }, + { 579, 579, 0, 0, 40000, 346,0 }, + { 580, 580, 0, 0, 40000, 353,0 }, + { 581, 581, 0, 0, 40000, 100,0 }, + { 582, 582, 0, 0, 40000, 133,0 }, + { 583, 583, 0, 0, 2286, 713,0 }, + { 584, 584, 0, 0, 40000, 193,0 }, + { 585, 585, 0, 0, 40000, 0,0 }, + { 516, 516, 0, 0, 633, 240,0 }, + { 586, 586, 0, 0, 40000, 73,0 }, + { 587, 587, 0, 0, 40000, 73,0 }, + { 588, 588, 0, 0, 40000, 73,0 }, + { 498, 498, 26, 0, 5293, 1253,0 }, + { 494, 494, 35, 0, 3800, 913,0 }, + { 350, 350, 41, 0, 380, 153,0 }, + { 353, 353, 48, 0, 173, 100,0 }, + { 354, 354, 67, 0, 246, 120,0 }, + { 502, 502, 24, 0, 340, 146,0 }, + { 346, 346, 36, 0, 406, 73,0 }, + { 346, 346, 38, 0, 406, 20,0 }, + { 346, 346, 40, 0, 406, 73,0 }, + { 346, 346, 42, 0, 406, 20,0 }, + { 346, 346, 44, 0, 306, 20,0 }, + { 510, 510, 55, 0, 1866, 646,0 }, + { 346, 346, 46, 0, 306, 20,0 }, + { 136, 136, 80, 0, 1600, 573,0 }, + { 486, 486, 24, 0, 1193, 426,0 }, + { 153, 153, 50, 0, 106, 40,0 }, + { 346, 346, 24, 0, 540, 73,0 }, + { 516, 516, 31, 0, 626, 240,0 }, + { 498, 498, 35, 0, 3760, 880,0 }, + { 517, 517, 60, 0, 286, 133,0 }, + { 530, 530, 36, 0, 40000, 0,0 }, + { 530, 530, 48, 0, 40000, 0,0 }, + { 589, 589, 0, 0, 40000, 0,0 }, + { 139, 139, 76, 0, 253, 106,0 }, + { 156, 156, 48, 0, 206, 80,0 }, + { 157, 157, 48, 0, 426, 106,0 }, + { 165, 165, 69, 0, 120, 66,0 }, + { 167, 167, 75, 0, 546, 306,0 }, + { 590, 590, 0, 0, 40000, 0,0 }, + { 591, 591, 0, 0, 15486, 1580,0 }, + { 592, 592, 0, 0, 3446, 106,0 }, + { 593, 593, 0, 0, 1926, 146,0 }, + { 594, 594, 0, 0, 7293, 2380,0 }, + { 595, 595, 0, 0, 7613, 1566,0 }, + { 596, 596, 0, 0, 1153, 460,0 }, + { 597, 597, 0, 0, 1166, 400,0 }, + { 598, 598, 0, 0, 40000, 73,0 }, + { 599, 599, 0, 0, 40000, 766,0 }, + { 600, 600, 0, 0, 40000, 80,0 }, + { 601, 601, 0, 0, 1840, 513,0 }, + { 602, 602, 0, 0, 40000, 0,0 }, + { 603, 603, 0, 0, 4480, 733,0 }, + { 604, 604, 0, 0, 18226, 786,0 }, + { 605, 605, 0, 0, 4333, 233,0 }, + { 606, 606, 0, 0, 40000, 106,0 }, + { 607, 607, 0, 0, 40000, 366,0 }, + { 608, 608, 0, 0, 40000, 200,0 }, + { 609, 609, 0, 0, 713, 200,0 }, + { 610, 610, 0, 0, 8866, 1366,0 }, + { 611, 611, 0, 0, 2300, 73,0 }, + { 612, 612, 0, 0, 40000, 126,0 }, + { 613, 613, 0, 0, 40000, 1413,0 }, + { 614, 614, 0, 0, 40000, 333,0 }, + { 615, 615, 0, 0, 40000, 333,0 }, + { 616, 616, 0, 0, 40000, 26,0 }, + { 617, 617, 0, 0, 40000, 40,0 }, + { 618, 618, 0, 0, 4240, 353,0 }, + { 619, 619, 0, 0, 40000, 0,0 }, + { 620, 620, 0, 0, 40000, 73,0 }, + { 621, 621, 0, 0, 9020, 60,0 }, + { 622, 622, 0, 0, 3020, 0,0 }, + { 623, 623, 0, 0, 40000, 60,0 }, + { 624, 624, 0, 0, 40000, 73,0 }, + { 625, 625, 0, 0, 40000, 60,0 }, + { 626, 626, 0, 0, 40000, 53,0 }, + { 627, 627, 0, 0, 40000, 0,0 }, + { 628, 628, 0, 0, 40000, 66,0 }, + { 629, 629, 0, 0, 40000, 66,0 }, + { 630, 630, 0, 0, 5913, 426,0 }, + { 631, 631, 0, 0, 40000, 246,0 }, + { 632, 632, 0, 0, 40000, 206,0 }, + { 633, 633, 0, 0, 40000, 0,0 }, + { 634, 634, 0, 0, 2453, 780,0 }, + { 635, 635, 0, 0, 4740, 240,0 }, + { 636, 636, 0, 0, 1840, 353,0 }, + { 637, 637, 0, 0, 40000, 86,0 }, + { 638, 638, 0, 0, 3446, 1786,0 }, + { 346, 346, 0, 0, 540, 20,0 }, + { 639, 639, 0, 0, 7406, 2486,0 }, + { 404, 404, 0, 0, 1220, 466,0 }, + { 506, 506, 0, 0, 1000, 813,0 }, + { 639, 639, 60, 0, 2666, 913,0 }, + { 639, 639, 79, 0, 1366, 486,0 }, + { 640, 640, 65, 0, 2053, 646,0 }, + { 486, 486, 31, 0, 1206, 440,0 }, + { 486, 486, 36, 0, 1200, 433,0 }, + { 640, 640, 72, 0, 1713, 520,0 }, + { 136, 136, 79, 0, 1580, 560,0 }, + { 148, 148, 57, 0, 520, 206,0 }, + { 150, 150, 53, 0, 500, 193,0 }, + { 641, 641, 84, 0, 226, 66,0 }, + { 520, 520, 66, 0, 173, 20,0 }, + { 642, 642, 31, 0, 40000, 113,0 }, + { 642, 642, 29, 0, 40000, 113,0 }, + { 356, 356, 31, 0, 1366, 486,0 }, + { 356, 356, 19, 0, 1866, 633,0 }, + { 643, 643, 31, 0, 40000, 73,0 }, + { 643, 643, 29, 0, 40000, 73,0 }, + { 644, 644, 31, 0, 2286, 400,0 }, + { 644, 644, 35, 0, 2313, 420,0 }, + { 644, 644, 40, 0, 2353, 433,0 }, + { 644, 644, 47, 0, 1860, 346,0 }, + { 516, 516, 32, 0, 626, 240,0 }, + { 516, 516, 43, 0, 506, 200,0 }, + { 495, 495, 26, 0, 3180, 240,0 }, + { 495, 495, 44, 0, 2553, 206,0 }, + { 496, 496, 26, 0, 160, 73,0 }, + { 496, 496, 51, 0, 146, 66,0 }, + { 496, 496, 39, 0, 160, 73,0 }, + { 495, 495, 30, 0, 3180, 240,0 }, + { 645, 645, 44, 0, 1880, 653,0 }, + { 645, 645, 43, 0, 1886, 653,0 }, + { 646, 646, 0, 0, 2393, 833,0 }, + { 647, 647, 0, 0, 4693, 26,0 }, + { 648, 648, 0, 0, 2306, 773,0 }, + { 649, 649, 0, 0, 40000, 120,0 }, + { 650, 650, 0, 0, 40000, 66,0 }, + { 651, 651, 0, 0, 5866, 1206,0 }, + { 652, 652, 0, 0, 40000, 426,0 }, + { 653, 653, 0, 0, 1873, 633,0 }, + { 654, 654, 0, 0, 40000, 66,0 }, + { 655, 655, 0, 0, 40000, 73,0 }, + { 656, 656, 0, 0, 40000, 73,0 }, + { 657, 657, 0, 0, 40000, 0,0 }, + { 658, 658, 0, 0, 2040, 380,0 }, + { 659, 659, 0, 0, 40000, 73,0 }, + { 660, 660, 0, 0, 3720, 1260,0 }, + { 661, 661, 0, 0, 4080, 1046,0 }, + { 662, 662, 0, 0, 8693, 4666,0 }, + { 663, 663, 0, 0, 1926, 73,0 }, + { 664, 664, 0, 0, 8326, 646,0 }, + { 665, 665, 0, 0, 40000, 240,0 }, + { 666, 666, 0, 0, 40000, 226,0 }, + { 667, 667, 0, 0, 40000, 220,0 }, + { 668, 668, 0, 0, 40000, 0,0 }, + { 669, 669, 0, 0, 40000, 193,0 }, + { 670, 670, 0, 0, 880, 20,0 }, + { 671, 671, 0, 0, 4873, 120,0 }, + { 672, 672, 0, 0, 40000, 413,0 }, + { 673, 673, 0, 0, 700, 106,0 }, + { 674, 674, 0, 0, 700, 100,0 }, + { 675, 675, 0, 0, 40000, 126,0 }, + { 676, 676, 0, 0, 8113, 806,0 }, + { 677, 677, 0, 0, 8900, 80,0 }, + { 678, 678, 0, 0, 1893, 653,0 }, + { 679, 679, 0, 0, 3973, 206,0 }, + { 680, 680, 0, 0, 40000, 173,0 }, + { 681, 681, 0, 0, 40000, 73,0 }, + { 682, 682, 0, 0, 40000, 93,0 }, + { 683, 683, 0, 0, 1606, 640,0 }, + { 684, 684, 0, 0, 15486, 1580,0 }, + { 685, 685, 0, 0, 40000, 346,0 }, + { 686, 686, 0, 0, 40000, 786,0 }, + { 687, 687, 0, 0, 386, 240,0 }, + { 688, 688, 0, 0, 40000, 2066,0 }, + { 689, 689, 0, 0, 15453, 73,0 }, + { 690, 690, 0, 0, 1206, 240,0 }, + { 691, 691, 0, 0, 8866, 1366,0 }, + { 692, 692, 0, 0, 5913, 2253,0 }, + { 693, 693, 0, 0, 773, 106,0 }, + { 694, 694, 0, 0, 3793, 73,0 }, + { 695, 695, 0, 0, 40000, 73,0 }, + { 645, 645, 0, 0, 3633, 1180,0 }, + { 696, 696, 0, 0, 40000, 80,0 }, + { 697, 697, 0, 0, 40000, 0,0 }, + { 698, 698, 0, 0, 40000, 66,0 }, + { 699, 699, 0, 0, 40000, 66,0 }, + { 700, 700, 0, 0, 106, 0,0 }, + { 701, 701, 0, 0, 40000, 200,0 }, + { 702, 702, 0, 0, 3913, 73,0 }, + { 703, 703, 0, 0, 40000, 73,0 }, + { 704, 704, 0, 0, 40000, 73,0 }, + { 705, 705, 0, 0, 40000, 73,0 }, + { 706, 706, 0, 0, 40000, 66,0 }, + { 707, 707, 0, 0, 40000, 313,0 }, + { 708, 708, 0, 0, 40000, 100,0 }, + { 709, 709, 0, 0, 40000, 213,0 }, + { 710, 710, 0, 0, 40000, 53,0 }, + { 711, 711, 0, 0, 40000, 40,0 }, + { 712, 712, 0, 0, 40000, 73,0 }, + { 713, 713, 0, 0, 40000, 140,0 }, + { 714, 714, 0, 0, 40000, 606,0 }, + { 715, 715, 0, 0, 40000, 226,0 }, + { 716, 716, 0, 0, 3746, 1273,0 }, + { 717, 717, 0, 0, 40000, 80,0 }, + { 718, 718, 0, 0, 2360, 806,0 }, + { 719, 719, 0, 0, 1186, 420,0 }, + { 720, 720, 0, 0, 12533, 1953,0 }, + { 721, 721, 0, 0, 973, 1280,0 }, + { 722, 722, 0, 0, 40000, 426,0 }, + { 723, 723, 0, 0, 40000, 53,0 }, + { 724, 724, 0, 0, 40000, 66,0 }, + { 725, 725, 0, 0, 1246, 73,0 }, + { 726, 726, 0, 0, 3726, 1246,0 }, + { 727, 727, 0, 0, 2346, 813,0 }, + { 728, 728, 0, 0, 1206, 433,0 }, + { 507, 507, 0, 0, 306, 246,0 }, + { 512, 512, 0, 0, 526, 840,0 }, + { 729, 729, 0, 0, 14793, 4933,0 }, + { 730, 730, 0, 0, 14640, 4806,0 }, + { 731, 731, 0, 0, 5233, 633,0 }, + { 732, 732, 0, 0, 40000, 2513,0 }, + { 733, 733, 0, 0, 40000, 820,0 }, + { 734, 734, 0, 0, 40000, 0,0 }, + { 735, 735, 0, 0, 1726, 793,0 }, + { 736, 736, 0, 0, 513, 20,0 }, + { 737, 737, 0, 2, 6, 0,0 }, + { 738, 738, 38, 0, 1020, 413,0 }, + { 739, 739, 44, 0, 220, 33,0 }, + { 500, 500, 58, 0, 100, 0,0 }, + { 740, 740, 24, 0, 513, 206,0 }, + { 741, 741, 60, 0, 220, 26,0 }, + { 736, 736, 44, 0, 286, 20,0 }, + { 742, 742, 25, 0, 626, 246,0 }, + { 743, 743, 60, 0, 146, 86,0 }, + { 742, 742, 30, 0, 626, 240,0 }, + { 377, 377, 60, 0, 446, 626,0 }, + { 742, 742, 33, 0, 620, 226,0 }, + { 744, 744, 60, 0, 220, 113,0 }, + { 742, 742, 35, 0, 620, 233,0 }, + { 742, 742, 37, 0, 633, 246,0 }, + { 745, 745, 0, 0, 1880, 640,0 }, + { 742, 742, 40, 0, 640, 260,0 }, + { 746, 746,102, 0, 960, 300,0 }, + { 747, 747, 80, 0, 1106, 126,0 }, + { 377, 377, 0, 0, 500, 760,0 }, + { 748, 748, 56, 0, 100, 0,0 }, + { 749, 749, 0, 0, 973, 1300,0 }, + { 746, 746,100, 0, 960, 340,0 }, + { 750, 750, 40, 0, 626, 240,0 }, + { 750, 750, 35, 0, 626, 240,0 }, + { 751, 751, 29, 0, 206, 106,0 }, + { 750, 750, 29, 0, 633, 240,0 }, + { 750, 750, 22, 0, 640, 233,0 }, + { 500, 500, 0, 0, 106, 0,0 }, + { 752, 752, 0, 0, 206, 26,0 }, + { 753, 753, 84, 0, 166, 20,0 }, + { 754, 754, 84, 0, 1580, 553,0 }, + { 755, 755, 0, 0, 633, 233,0 }, + { 755, 755, 71, 0, 440, 180,0 }, + { 755, 755, 53, 0, 513, 200,0 }, + { 755, 755, 48, 0, 520, 206,0 }, + { 756, 756, 95, 0, 286, 20,0 }, + { 757, 757, 95, 0, 1880, 20,0 }, + { 758, 758, 0, 0, 14413, 333,0 }, + { 759, 759, 0, 0, 14453, 360,0 }, + { 760, 760, 0, 0, 14940, 353,0 }, + { 761, 761, 0, 0, 7286, 340,0 }, + { 762, 762, 0, 0, 14700, 60,0 }, + { 763, 763, 0, 0, 14506, 340,0 }, + { 764, 764, 0, 0, 14706, 200,0 }, + { 765, 765, 0, 0, 40000, 0,0 }, + { 766, 766, 0, 0, 2900, 426,0 }, + { 767, 767, 0, 0, 2986, 753,0 }, + { 768, 768, 0, 0, 1706, 680,0 }, + { 769, 769, 0, 0, 14646, 1253,0 }, + { 770, 770, 0, 0, 1713, 486,0 }, + { 771, 771, 0, 0, 966, 346,0 }, + { 772, 772, 0, 0, 3453, 766,0 }, + { 773, 773, 0, 0, 2866, 486,0 }, + { 774, 774, 0, 0, 40000, 73,0 }, + { 775, 775, 0, 0, 40000, 73,0 }, + { 776, 776, 0, 0, 40000, 166,0 }, + { 777, 777, 0, 0, 40000, 126,0 }, + { 778, 778, 0, 0, 40000, 113,0 }, + { 779, 779, 0, 0, 40000, 113,0 }, + { 780, 780, 0, 0, 40000, 93,0 }, + { 781, 781, 0, 0, 40000, 200,0 }, + { 782, 782, 0, 0, 7186, 93,0 }, + { 783, 783, 0, 0, 6406, 120,0 }, + { 784, 784, 0, 0, 40000, 0,0 }, + { 785, 785, 0, 0, 40000, 0,0 }, + { 786, 786, 0, 0, 1220, 73,0 }, + { 787, 787, 0, 0, 40000, 0,0 }, + { 788, 788, 0, 0, 17566, 66,0 }, + { 789, 789, 0, 0, 2333, 26,0 }, + { 790, 790, 0, 0, 4560, 153,0 }, + { 791, 791, 0, 0, 40000, 0,0 }, + { 792, 792, 0, 0, 40000, 0,0 }, + { 793, 793, 0, 0, 40000, 0,0 }, + { 794, 794, 0, 0, 2506, 126,0 }, + { 795, 795, 0, 0, 2513, 126,0 }, + { 796, 796, 0, 0, 40000, 0,0 }, + { 797, 797, 0, 0, 3386, 80,0 }, + { 798, 798, 0, 0, 40000, 100,0 }, + { 799, 799, 0, 0, 40000, 100,0 }, + { 800, 800, 0, 0, 40000, 120,0 }, + { 801, 801, 0, 0, 40000, 0,0 }, + { 802, 802, 0, 0, 40000, 200,0 }, + { 803, 803, 0, 0, 1080, 180,0 }, + { 804, 804, 0, 0, 3620, 1166,0 }, + { 805, 805, 0, 0, 1186, 393,0 }, + { 806, 806, 0, 0, 40000, 213,0 }, + { 807, 807, 0, 0, 40000, 426,0 }, + { 808, 808, 0, 0, 40000, 146,0 }, + { 809, 809, 0, 0, 40000, 146,0 }, + { 810, 810, 0, 0, 40000, 60,0 }, + { 811, 811, 0, 0, 40000, 113,0 }, + { 812, 812, 0, 0, 40000, 93,0 }, + { 813, 813, 0, 0, 1186, 153,0 }, + { 814, 814, 0, 0, 40000, 0,0 }, + { 815, 815, 0, 0, 40000, 80,0 }, + { 816, 816, 0, 0, 40000, 80,0 }, + { 817, 817, 0, 0, 40000, 46,0 }, + { 818, 818, 0, 0, 40000, 0,0 }, + { 819, 819, 0, 0, 40000, 66,0 }, + { 820, 820, 0, 0, 40000, 126,0 }, + { 821, 821, 0, 0, 40000, 213,0 }, + { 822, 822, 0, 0, 40000, 80,0 }, + { 823, 823, 0, 0, 40000, 73,0 }, + { 824, 824, 0, 0, 40000, 73,0 }, + { 825, 825, 0, 0, 40000, 100,0 }, + { 826, 826, 0, 0, 40000, 93,0 }, + { 827, 827, 0, 0, 40000, 73,0 }, + { 828, 828, 0, 0, 40000, 73,0 }, + { 829, 829, 0, 0, 40000, 80,0 }, + { 830, 830, 0, 0, 40000, 80,0 }, + { 831, 831, 0, 0, 40000, 80,0 }, + { 832, 832, 0, 0, 40000, 73,0 }, + { 833, 833, 0, 0, 40000, 80,0 }, + { 834, 834, 0, 0, 40000, 86,0 }, + { 835, 835, 0, 0, 40000, 100,0 }, + { 836, 836, 0, 0, 40000, 100,0 }, + { 837, 837, 0, 0, 40000, 140,0 }, + { 838, 838, 0, 0, 40000, 73,0 }, + { 839, 839, 0, 0, 40000, 0,0 }, + { 840, 840, 0, 0, 40000, 93,0 }, + { 841, 841, 0, 0, 40000, 0,0 }, + { 842, 842, 0, 0, 40000, 0,0 }, + { 843, 843, 0, 0, 40000, 73,0 }, + { 844, 844, 0, 0, 40000, 66,0 }, + { 845, 845, 0, 0, 40000, 0,0 }, + { 846, 846, 0, 0, 40000, 193,0 }, + { 847, 847, 0, 0, 40000, 340,0 }, + { 848, 848, 0, 0, 40000, 233,0 }, + { 849, 849, 0, 0, 40000, 80,0 }, + { 850, 850, 0, 0, 40000, 186,0 }, + { 851, 851, 0, 0, 9973, 426,0 }, + { 852, 852, 0, 0, 40000, 200,0 }, + { 853, 853, 0, 0, 40000, 400,0 }, + { 854, 854, 0, 0, 14633, 200,0 }, + { 855, 855, 0, 0, 40000, 333,0 }, + { 856, 856, 0, 0, 4620, 800,0 }, + { 857, 857, 0, 0, 8940, 386,0 }, + { 858, 858, 0, 0, 8966, 740,0 }, + { 859, 859, 0, 0, 40000, 273,0 }, + { 860, 860, 0, 0, 40000, 126,0 }, + { 861, 861, 0, 0, 40000, 400,0 }, + { 862, 862, 0, 0, 4480, 213,0 }, + { 863, 863, 0, 0, 633, 100,0 }, + { 864, 864, 0, 0, 3740, 353,0 }, + { 865, 865, 0, 0, 2333, 406,0 }, + { 866, 866, 0, 0, 1933, 566,0 }, + { 867, 867, 0, 0, 40000, 93,0 }, + { 868, 868, 0, 0, 40000, 106,0 }, + { 869, 869, 0, 0, 40000, 100,0 }, + { 870, 870, 0, 0, 3093, 240,0 }, + { 871, 871, 0, 0, 513, 93,0 }, + { 872, 872, 0, 0, 700, 180,0 }, + { 361, 361, 0, 0, 373, 40,0 }, + { 873, 873, 0, 0, 1046, 446,0 }, + { 874, 874, 0, 0, 1886, 520,0 }, + { 875, 875, 0, 0, 1226, 366,0 }, + { 876, 876, 0, 0, 4193, 73,0 }, + { 877, 877, 0, 0, 826, 120,0 }, + { 878, 878, 0, 0, 280, 146,0 }, + { 879, 879, 0, 0, 5266, 806,0 }, + { 880, 880, 0, 0, 386, 80,0 }, + { 881, 881, 0, 0, 40000, 100,0 }, + { 882, 882, 0, 0, 40000, 413,0 }, + { 883, 883, 0, 0, 40000, 0,0 }, + { 884, 884, 36, 0, 233, 80,0 }, + { 885, 885, 48, 0, 193, 93,0 }, + { 885, 885, 36, 0, 226, 100,0 }, + { 886, 886, 36, 0, 113, 0,0 }, + { 887, 887, 32, 0, 133, 40,0 }, + { 767, 767, 96, 0, 1760, 480,0 }, + { 888, 888, 30, 0, 246, 40,0 }, + { 889, 889, 35, 0, 420, 140,0 }, + { 890, 890, 60, 0, 240, 60,0 }, + { 884, 884, 59, 0, 146, 20,0 }, + { 890, 890, 44, 0, 240, 60,0 }, + { 891, 891, 41, 0, 713, 273,0 }, + { 892, 892, 47, 0, 173, 93,0 }, + { 891, 891, 44, 0, 513, 206,0 }, + { 891, 891, 48, 0, 506, 200,0 }, + { 893, 893, 62, 0, 1926, 93,0 }, + { 891, 891, 51, 0, 520, 200,0 }, + { 891, 891, 54, 0, 513, 206,0 }, + { 894, 894, 40, 0, 1280, 793,0 }, + { 891, 891, 57, 0, 380, 160,0 }, + { 895, 895, 97, 0, 233, 106,0 }, + { 896, 896, 50, 0, 220, 93,0 }, + { 376, 376, 60, 0, 1573, 713,0 }, + { 897, 897, 53, 0, 126, 73,0 }, + { 898, 898, 46, 0, 173, 133,0 }, + { 897, 897, 57, 0, 126, 33,0 }, + { 899, 899, 42, 0, 626, 233,0 }, + { 899, 899, 37, 0, 633, 240,0 }, + { 900, 900, 41, 0, 626, 240,0 }, + { 900, 900, 37, 0, 626, 240,0 }, + { 871, 871, 77, 0, 173, 40,0 }, + { 871, 871, 72, 0, 173, 40,0 }, + { 388, 388, 70, 0, 213, 86,0 }, + { 901, 901, 39, 0, 260, 26,0 }, + { 902, 902, 36, 0, 1093, 73,0 }, + { 903, 903, 46, 0, 120, 73,0 }, + { 904, 904, 48, 0, 766, 80,0 }, + { 905, 905, 85, 0, 126, 26,0 }, + { 361, 361, 66, 0, 180, 26,0 }, + { 906, 906, 41, 0, 193, 73,0 }, + { 907, 907, 41, 0, 333, 106,0 }, + { 908, 908, 81, 0, 160, 26,0 }, + { 400, 400, 10, 0, 1186, 413,0 }, + { 886, 886, 60, 0, 100, 0,0 }, + { 873, 873, 53, 0, 846, 360,0 }, + { 909, 909, 0, 0, 5593, 340,0 }, + { 910, 910, 0, 0, 14646, 346,0 }, + { 911, 911, 0, 0, 6826, 280,0 }, + { 912, 912, 0, 0, 7000, 306,0 }, + { 913, 913, 0, 0, 8793, 133,0 }, + { 914, 914, 0, 0, 14680, 346,0 }, + { 915, 915, 0, 0, 7246, 126,0 }, + { 916, 916, 0, 0, 40000, 0,0 }, + { 917, 917, 0, 0, 1866, 433,0 }, + { 362, 362, 0, 0, 1106, 340,0 }, + { 918, 918, 0, 0, 1053, 273,0 }, + { 919, 919, 0, 0, 14513, 1213,0 }, + { 920, 920, 0, 0, 1886, 646,0 }, + { 921, 921, 0, 0, 926, 313,0 }, + { 922, 922, 0, 0, 2340, 806,0 }, + { 923, 923, 0, 0, 2966, 553,0 }, + { 924, 924, 0, 0, 40000, 66,0 }, + { 925, 925, 0, 0, 40000, 73,0 }, + { 926, 926, 0, 0, 40000, 0,0 }, + { 927, 927, 0, 0, 40000, 126,0 }, + { 928, 928, 0, 0, 40000, 113,0 }, + { 929, 929, 0, 0, 40000, 113,0 }, + { 930, 930, 0, 0, 40000, 93,0 }, + { 931, 931, 0, 0, 40000, 113,0 }, + { 932, 932, 0, 0, 7200, 86,0 }, + { 933, 933, 0, 0, 5373, 106,0 }, + { 934, 934, 0, 0, 40000, 0,0 }, + { 935, 935, 0, 0, 40000, 0,0 }, + { 936, 936, 0, 0, 2380, 73,0 }, + { 937, 937, 0, 0, 40000, 0,0 }, + { 938, 938, 0, 0, 40000, 0,0 }, + { 939, 939, 0, 0, 6013, 53,0 }, + { 940, 940, 0, 0, 3713, 126,0 }, + { 941, 941, 0, 0, 17566, 26,0 }, + { 942, 942, 0, 0, 40000, 0,0 }, + { 943, 943, 0, 0, 40000, 0,0 }, + { 944, 944, 0, 0, 2506, 126,0 }, + { 945, 945, 0, 0, 3733, 73,0 }, + { 946, 946, 0, 0, 40000, 0,0 }, + { 947, 947, 0, 0, 3386, 80,0 }, + { 948, 948, 0, 0, 40000, 100,0 }, + { 949, 949, 0, 0, 40000, 100,0 }, + { 950, 950, 0, 0, 40000, 113,0 }, + { 951, 951, 0, 0, 40000, 0,0 }, + { 952, 952, 0, 0, 40000, 200,0 }, + { 953, 953, 0, 0, 1140, 213,0 }, + { 954, 954, 0, 0, 2140, 400,0 }, + { 955, 955, 0, 0, 813, 240,0 }, + { 956, 956, 0, 0, 40000, 100,0 }, + { 957, 957, 0, 0, 40000, 426,0 }, + { 958, 958, 0, 0, 40000, 0,0 }, + { 959, 959, 0, 0, 40000, 146,0 }, + { 960, 960, 0, 0, 40000, 120,0 }, + { 961, 961, 0, 0, 40000, 93,0 }, + { 962, 962, 0, 0, 1193, 153,0 }, + { 963, 963, 0, 0, 40000, 46,0 }, + { 964, 964, 0, 0, 40000, 80,0 }, + { 965, 965, 0, 0, 40000, 80,0 }, + { 966, 966, 0, 0, 40000, 20,0 }, + { 967, 967, 0, 0, 40000, 0,0 }, + { 968, 968, 0, 0, 40000, 93,0 }, + { 969, 969, 0, 0, 40000, 86,0 }, + { 970, 970, 0, 0, 40000, 213,0 }, + { 971, 971, 0, 0, 40000, 80,0 }, + { 972, 972, 0, 0, 40000, 73,0 }, + { 973, 973, 0, 0, 40000, 0,0 }, + { 974, 974, 0, 0, 40000, 93,0 }, + { 975, 975, 0, 0, 40000, 73,0 }, + { 976, 976, 0, 0, 40000, 73,0 }, + { 977, 977, 0, 0, 40000, 66,0 }, + { 978, 978, 0, 0, 40000, 66,0 }, + { 979, 979, 0, 0, 40000, 100,0 }, + { 980, 980, 0, 0, 40000, 73,0 }, + { 981, 981, 0, 0, 40000, 73,0 }, + { 982, 982, 0, 0, 40000, 80,0 }, + { 983, 983, 0, 0, 40000, 100,0 }, + { 984, 984, 0, 0, 40000, 100,0 }, + { 985, 985, 0, 0, 40000, 100,0 }, + { 986, 986, 0, 0, 40000, 80,0 }, + { 987, 987, 0, 0, 40000, 73,0 }, + { 988, 988, 0, 0, 40000, 0,0 }, + { 989, 989, 0, 0, 40000, 86,0 }, + { 990, 990, 0, 0, 40000, 0,0 }, + { 991, 991, 0, 0, 40000, 0,0 }, + { 992, 992, 0, 0, 40000, 80,0 }, + { 993, 993, 0, 0, 40000, 86,0 }, + { 994, 994, 0, 0, 40000, 0,0 }, + { 995, 995, 0, 0, 40000, 0,0 }, + { 996, 996, 0, 0, 40000, 333,0 }, + { 997, 997, 0, 0, 40000, 180,0 }, + { 998, 998, 0, 0, 40000, 80,0 }, + { 999, 999, 0, 0, 40000, 120,0 }, + {1000,1000, 0, 0, 10006, 460,0 }, + {1001,1001, 0, 0, 40000, 186,0 }, + {1002,1002, 0, 0, 40000, 400,0 }, + {1003,1003, 0, 0, 20333, 260,0 }, + {1004,1004, 0, 0, 40000, 373,0 }, + {1005,1005, 0, 0, 4520, 400,0 }, + {1006,1006, 0, 0, 8213, 306,0 }, + {1007,1007, 0, 0, 8646, 360,0 }, + {1008,1008, 0, 0, 40000, 160,0 }, + {1009,1009, 0, 0, 40000, 133,0 }, + {1010,1010, 0, 0, 40000, 400,0 }, + {1011,1011, 0, 0, 4473, 193,0 }, + {1012,1012, 0, 0, 1813, 0,0 }, + {1013,1013, 0, 0, 3726, 353,0 }, + {1014,1014, 0, 0, 4400, 373,0 }, + {1015,1015, 0, 0, 953, 166,0 }, + {1016,1016, 0, 0, 40000, 73,0 }, + {1017,1017, 0, 0, 40000, 100,0 }, + {1018,1018, 0, 0, 40000, 100,0 }, + {1019,1019, 0, 0, 3100, 240,0 }, + { 444, 444, 0, 0, 513, 93,0 }, + {1020,1020, 0, 0, 626, 180,0 }, + { 449, 449, 0, 0, 373, 80,0 }, + { 453, 453, 0, 0, 40000, 0,0 }, + {1021,1021, 0, 0, 1020, 340,0 }, + {1022,1022, 0, 0, 1200, 366,0 }, + {1023,1023, 0, 0, 4193, 73,0 }, + {1024,1024, 0, 0, 820, 120,0 }, + {1025,1025, 0, 0, 680, 213,0 }, + {1026,1026, 0, 0, 5260, 806,0 }, + {1027,1027, 0, 0, 9193, 86,0 }, + {1028,1028, 0, 0, 40000, 100,0 }, + {1029,1029, 0, 0, 40000, 426,0 }, + {1030,1030, 0, 0, 40000, 260,0 }, + {1031,1031, 0, 0, 3480, 66,0 }, + {1032,1032, 32, 0, 133, 46,0 }, + {1033,1033, 30, 0, 200, 40,0 }, + {1034,1034, 96, 0, 146, 73,0 }, + {1035,1035, 60, 0, 553, 186,0 }, + {1036,1036, 0, 0, 13193, 260,0 }, + {1037,1037, 0, 0, 40000, 100,0 }, + {1038,1038, 0, 0, 7980, 66,0 }, + {1039,1039, 0, 0, 40000, 0,0 }, + {1040,1040, 0, 0, 980, 340,0 }, + {1041,1041, 0, 0, 7413, 2480,0 }, + {1042,1042, 0, 0, 2906, 520,0 }, + {1043,1043, 0, 0, 40000, 73,0 }, + {1044,1044, 0, 0, 40000, 53,0 }, + {1045,1045, 0, 0, 40000, 113,0 }, + {1046,1046, 0, 0, 5380, 113,0 }, + {1047,1047, 0, 0, 40000, 0,0 }, + {1048,1048, 0, 0, 2366, 73,0 }, + {1049,1049, 0, 0, 40000, 0,0 }, + {1050,1050, 0, 0, 18293, 80,0 }, + {1051,1051, 0, 0, 18466, 146,0 }, + {1052,1052, 0, 0, 9220, 73,0 }, + {1053,1053, 0, 0, 40000, 240,0 }, + {1054,1054, 0, 0, 40000, 0,0 }, + {1055,1055, 0, 0, 1086, 126,0 }, + {1056,1056, 0, 0, 3766, 73,0 }, + {1057,1057, 0, 0, 1186, 226,0 }, + {1058,1058, 0, 0, 3373, 73,0 }, + {1059,1059, 0, 0, 40000, 246,0 }, + {1060,1060, 0, 0, 340, 220,0 }, + {1061,1061, 0, 0, 1186, 386,0 }, + {1062,1062, 0, 0, 40000, 253,0 }, + {1063,1063, 0, 0, 40000, 440,0 }, + {1064,1064, 0, 0, 40000, 46,0 }, + {1065,1065, 0, 0, 40000, 80,0 }, + {1066,1066, 0, 0, 40000, 126,0 }, + {1067,1067, 0, 0, 40000, 133,0 }, + {1068,1068, 0, 0, 40000, 93,0 }, + {1069,1069, 0, 0, 40000, 86,0 }, + {1070,1070, 0, 0, 40000, 93,0 }, + {1071,1071, 0, 0, 40000, 66,0 }, + {1072,1072, 0, 0, 40000, 93,0 }, + {1073,1073, 0, 0, 40000, 73,0 }, + {1074,1074, 0, 0, 40000, 173,0 }, + {1075,1075, 0, 0, 586, 193,0 }, + {1076,1076, 0, 0, 40000, 146,0 }, + {1077,1077, 0, 0, 18460, 73,0 }, + {1078,1078, 0, 0, 846, 93,0 }, + {1079,1079, 0, 0, 40000, 0,0 }, + {1080,1080, 0, 0, 40000, 86,0 }, + {1081,1081, 0, 0, 40000, 0,0 }, + {1082,1082, 0, 0, 40000, 353,0 }, + {1083,1083, 0, 0, 40000, 300,0 }, + {1084,1084, 0, 0, 40000, 320,0 }, + {1085,1085, 0, 0, 9920, 1553,0 }, + {1086,1086, 0, 0, 40000, 386,0 }, + {1087,1087, 0, 0, 40000, 0,0 }, + {1088,1088, 0, 0, 9980, 873,0 }, + {1089,1089, 0, 0, 40000, 386,0 }, + {1090,1090, 0, 0, 966, 126,0 }, + {1091,1091, 0, 0, 40000, 820,0 }, + {1092,1092, 0, 0, 8620, 366,0 }, + {1093,1093, 0, 0, 40000, 826,0 }, + {1094,1094, 0, 0, 40000, 433,0 }, + {1095,1095, 0, 0, 633, 73,0 }, + {1096,1096, 0, 0, 3693, 126,0 }, + {1097,1097, 0, 0, 40000, 0,0 }, + {1098,1098, 0, 0, 40000, 153,0 }, + {1099,1099, 0, 0, 40000, 0,0 }, + {1100,1100, 0, 0, 40000, 0,0 }, + {1101,1101, 0, 0, 40000, 306,0 }, + {1102,1102, 0, 0, 3666, 3093,0 }, + {1103,1103, 0, 0, 1873, 653,0 }, + {1104,1104, 0, 0, 40000, 0,0 }, + {1105,1105, 0, 0, 11293, 886,0 }, + {1106,1106, 0, 0, 40000, 546,0 }, + { 430, 430, 0, 0, 1146, 80,0 }, + {1107,1107, 35, 0, 580, 80,0 }, + {1090,1090, 77, 0, 280, 60,0 }, + {1090,1090, 72, 0, 280, 60,0 }, + {1108,1108, 0, 0, 10180, 600,0 }, + {1109,1109, 0, 0, 10053, 353,0 }, + {1110,1111, 0, 1, 9940, 480,0 }, + {1112,1113, 0, 1, 10620, 473,0.03125 }, + {1114,1114, 0, 0, 40000, 0,0 }, + {1115,1116, 0, 1, 9833, 220,0 }, + {1117,1117, 0, 0, 10286, 473,0 }, + {1118,1118, 0, 0, 7686, 93,0 }, + {1119,1119, 0, 0, 7220, 613,0 }, + {1120,1120, 0, 0, 11513, 1666,0 }, + {1121,1121, 0, 0, 5200, 1700,0 }, + {1122,1122, 0, 0, 10173, 626,0 }, + {1123,1123, 0, 0, 1206, 380,0 }, + {1124,1124, 0, 0, 1953, 866,0 }, + {1125,1125, 0, 0, 4686, 1586,0 }, + {1126,1126, 0, 0, 3786, 893,0 }, + {1127,1127, 0, 0, 40000, 126,0 }, + {1128,1128, 0, 0, 40000, 120,0 }, + {1129,1130, 0, 1, 40000, 146,0.15625 }, + {1131,1131, 0, 0, 40000, 433,0 }, + {1132,1132, 0, 0, 40000, 133,0 }, + {1133,1134, 0, 1, 40000, 126,-0.046875 }, + {1135,1135, 0, 0, 40000, 113,0 }, + {1136,1137, 0, 1, 40000, 253,2.5e-05 }, + {1138,1138, 0, 0, 18440, 240,0 }, + {1139,1139, 0, 0, 5213, 886,0 }, + {1140,1140, 0, 0, 1446, 113,0 }, + {1141,1141, 0, 0, 5233, 106,0 }, + {1142,1142, 0, 0, 5286, 266,0 }, + {1143,1143, 0, 0, 40000, 66,0 }, + {1144,1144, 0, 0, 40000, 66,0 }, + {1145,1145, 0, 0, 10593, 106,0 }, + {1146,1146, 0, 0, 2733, 160,0 }, + {1147,1147, 0, 0, 10313, 93,0 }, + {1148,1148, 0, 0, 40000, 0,0 }, + {1149,1150, 0, 1, 40000, 0,-0.03125 }, + {1151,1151, 0, 0, 40000, 53,0 }, + {1152,1152, 0, 0, 10560, 246,0 }, + {1153,1153, 0, 0, 2700, 153,0 }, + {1154,1154, 0, 1, 40000, 100,-0.15625 }, + {1155,1155, 0, 0, 40000, 73,0 }, + {1156,1156, 0, 0, 40000, 220,0 }, + {1157,1157, 0, 0, 40000, 140,0 }, + {1158,1158, 0, 0, 40000, 380,0 }, + {1159,1160, 0, 1, 40000, 400,0.171875 }, + {1161,1161, 0, 0, 40000, 0,0 }, + {1162,1162, 0, 0, 40000, 0,0 }, + {1163,1163, 0, 0, 4733, 906,0 }, + {1164,1165, 0, 1, 40000, 393,-0.125 }, + {1166,1167, 0, 1, 40000, 366,0.078125 }, + {1168,1168, 0, 1, 40000, 2453,-0.078125 }, + {1169,1170, 0, 1, 40000, 546,0.0625 }, + {1171,1172, 0, 1, 40000, 786,0.15625 }, + {1173,1173, 0, 0, 40000, 0,0 }, + {1174,1174, 0, 0, 40000, 513,0 }, + {1175,1176, 0, 1, 2300, 533,0 }, + {1177,1177, 0, 0, 40000, 80,0 }, + {1178,1178, 0, 0, 40000, 60,0 }, + {1179,1179, 0, 0, 40000, 0,0 }, + {1180,1180, 0, 0, 10653, 86,0 }, + {1181,1182, 0, 1, 40000, 0,2.5e-05 }, + {1183,1184, 0, 1, 40000, 86,0.046875 }, + {1185,1186, 0, 1, 40000, 0,0.09375 }, + {1187,1188, 0, 1, 40000, 0,0.09375 }, + {1189,1189, 0, 0, 40000, 133,0 }, + {1190,1190, 0, 0, 40000, 140,0 }, + {1191,1191, 0, 0, 40000, 73,0 }, + {1192,1192, 0, 0, 40000, 60,0 }, + {1193,1193, 0, 0, 40000, 106,0 }, + {1194,1194, 0, 0, 40000, 93,0 }, + {1195,1195, 0, 0, 40000, 66,0 }, + {1196,1196, 0, 0, 40000, 93,0 }, + {1197,1197, 0, 0, 40000, 60,0 }, + {1198,1198, 0, 0, 40000, 66,0 }, + {1199,1199, 0, 0, 40000, 120,0 }, + {1200,1200, 0, 0, 40000, 100,0 }, + {1201,1201, 0, 0, 40000, 86,0 }, + {1202,1202, 0, 0, 40000, 0,0 }, + {1203,1203, 0, 0, 40000, 233,0 }, + {1204,1204, 0, 0, 40000, 100,0 }, + {1205,1206, 0, 1, 40000, 266,0.03125 }, + {1207,1208, 0, 1, 40000, 260,-2.5e-05 }, + {1209,1209, 0, 0, 40000, 146,0 }, + {1210,1211, 0, 1, 40000, 60,0.03125 }, + {1212,1212, 0, 0, 40000, 53,0 }, + {1213,1214, 0, 1, 40000, 706,-0.09375 }, + {1215,1216, 0, 1, 40000, 660,-0.046875 }, + {1217,1217, 0, 0, 40000, 133,0 }, + {1218,1219, 0, 1, 40000, 426,0.03125 }, + {1220,1220, 0, 1, 40000, 0,0.03125 }, + {1221,1222, 0, 1, 40000, 260,0.171875 }, + {1223,1223, 0, 0, 40000, 0,0 }, + {1224,1224, 0, 0, 6100, 1580,0 }, + {1225,1150, 0, 1, 40000, 73,-0.03125 }, + {1226,1226, 0, 0, 40000, 1580,0 }, + {1227,1227, 0, 0, 40000, 40,0 }, + {1228,1229, 0, 1, 40000, 113,0.125 }, + {1230,1230, 0, 0, 2666, 846,0 }, + {1231,1232, 0, 1, 40000, 0,-0.03125 }, + {1233,1234, 0, 1, 9233, 2413,-0.1875 }, + {1235,1235, 0, 0, 40000, 1020,0 }, + {1236,1236, 0, 0, 40000, 0,0 }, + {1237,1237, 0, 0, 9633, 3073,0 }, + {1238,1238, 0, 0, 40000, 0,0 }, + {1239,1239, 0, 0, 2446, 386,0 }, + {1240,1241, 0, 1, 3113, 1133,0 }, + {1242,1242, 0, 0, 18473, 813,0 }, + {1243,1243, 0, 0, 1206, 660,0 }, + {1244,1244, 0, 0, 40000, 153,0 }, + {1245,1245, 0, 0, 40000, 160,0 }, + {1246,1246, 0, 0, 40000, 133,0 }, + {1247,1247, 0, 0, 8660, 2386,0 }, + {1248,1248, 0, 0, 293, 106,0 }, + {1249,1249, 0, 0, 40000, 433,0 }, + {1250,1250, 0, 0, 426, 80,0 }, + {1251,1251, 0, 0, 973, 360,0 }, + {1252,1252, 0, 0, 573, 153,0 }, + {1253,1253, 0, 0, 3746, 126,0 }, + {1254,1254, 0, 0, 2313, 73,0 }, + {1255,1255, 0, 0, 1473, 106,0 }, + {1256,1256, 0, 0, 1500, 320,0 }, + {1257,1257, 0, 0, 5280, 1593,0 }, + {1258,1258, 0, 0, 40000, 60,0 }, + {1259,1259, 0, 0, 40000, 146,0 }, + {1260,1260, 29, 0, 40000, 300,0 }, + {1261,1261, 65, 0, 40000, 2040,0 }, + {1262,1262, 0, 0, 626, 240,0 }, + {1263,1263, 25, 0, 626, 226,0 }, + {1264,1264, 83, 0, 180, 80,0 }, + {1265,1265, 32, 0, 260, 140,0 }, + {1266,1266, 60, 0, 40000, 0,0 }, + {1267,1267, 36, 0, 286, 40,0 }, + {1268,1268, 27, 0, 573, 80,0 }, + {1269,1269, 31, 0, 693, 106,0 }, + {1270,1270, 21, 0, 500, 146,0 }, + {1270,1270, 26, 0, 493, 140,0 }, + {1270,1270, 28, 0, 500, 146,0 }, + {1271,1271, 60, 0, 2420, 1080,0 }, + {1270,1270, 32, 0, 413, 126,0 }, + {1272,1272, 60, 0, 806, 300,0 }, + {1273,1273, 96, 0, 1146, 493,0 }, + {1274,1274, 72, 0, 1246, 586,0 }, + {1275,1275, 79, 0, 286, 106,0 }, + {1276,1276, 69, 0, 1193, 1046,0 }, + {1277,1277, 71, 0, 340, 93,0 }, + {1278,1278, 22, 0, 1880, 653,0 }, + {1279,1279, 55, 0, 246, 120,0 }, + {1279,1279, 48, 0, 286, 133,0 }, + {1280,1280, 0, 0, 40, 0,0 }, + {1281,1281, 49, 2, 40, 0,0 }, + {1282,1282, 73, 0, 166, 33,0 }, + {1282,1282, 68, 0, 166, 33,0 }, + {1282,1282, 61, 0, 200, 40,0 }, + {1283,1283, 0, 0, 40, 0,0 }, + {1284,1284, 0, 0, 40000, 100,0 }, + {1285,1285, 0, 0, 40000, 60,0 }, + {1286,1286, 0, 0, 40000, 0,0 }, + {1287,1287, 0, 0, 10460, 153,0 }, + {1288,1289, 0, 1, 40000, 0,0 }, + {1290,1290, 0, 0, 40000, 0,0 }, + {1291,1292, 36, 1, 353, 153,0 }, + {1293,1293, 69, 0, 1206, 1060,0 }, + {1294,1294, 0, 0, 40000, 0,0 }, + {1295,1295, 0, 0, 40000, 73,0 }, + {1296,1296, 0, 0, 40000, 0,0 }, + {1297,1297, 22, 0, 1880, 653,0 }, + {1298,1298, 0, 0, 40000, 73,0 }, + {1299,1299, 0, 0, 3913, 420,0 }, + {1300,1300, 0, 0, 9233, 240,0 }, + {1301,1301, 0, 0, 4660, 1573,0 }, + {1302,1302, 0, 0, 1166, 400,0 }, + {1303,1303, 0, 0, 40000, 126,0 }, + {1304,1304, 0, 0, 40000, 93,0 }, + {1305,1305, 0, 0, 40000, 93,0 }, + {1306,1306, 0, 0, 40000, 553,0 }, + {1307,1307, 0, 0, 40000, 660,0 }, + {1308,1308, 0, 0, 40000, 73,0 }, + {1309,1309, 0, 0, 40000, 146,0 }, + {1310,1310, 0, 0, 40000, 146,0 }, + {1311,1311, 0, 0, 4026, 100,0 }, + {1312,1312, 0, 0, 18226, 100,0 }, + {1313,1313, 0, 0, 40000, 0,0 }, + {1314,1314, 0, 0, 40000, 73,0 }, + {1315,1315, 0, 0, 40000, 140,0 }, + {1316,1316, 0, 0, 40000, 393,0 }, + {1317,1317, 0, 0, 40000, 406,0 }, + {1318,1318, 0, 0, 40000, 373,0 }, + {1319,1319, 0, 0, 40000, 0,0 }, + {1320,1320, 0, 0, 40000, 360,0 }, + {1321,1321, 0, 0, 1060, 380,0 }, + {1322,1322, 0, 0, 40000, 66,0 }, + {1323,1323, 0, 0, 40000, 66,0 }, + {1324,1324, 0, 0, 40000, 86,0 }, + {1325,1325, 0, 0, 40000, 73,0 }, + { 260, 260, 0, 0, 40000, 80,0 }, + {1326,1326, 0, 0, 40000, 80,0 }, + {1327,1327, 0, 0, 40000, 73,0 }, + {1328,1328, 0, 0, 40000, 73,0 }, + {1329,1329, 0, 0, 40000, 153,0 }, + {1330,1330, 0, 0, 40000, 153,0 }, + {1331,1331, 0, 0, 40000, 146,0 }, + {1332,1332, 0, 0, 40000, 146,0 }, + {1333,1333, 0, 0, 40000, 73,0 }, + {1334,1334, 0, 0, 40000, 153,0 }, + {1335,1335, 0, 0, 40000, 233,0 }, + {1336,1336, 0, 0, 40000, 400,0 }, + {1337,1337, 0, 0, 40000, 1373,0 }, + {1338,1338, 0, 0, 40000, 193,0 }, + {1339,1339, 0, 0, 40000, 1273,0 }, + {1340,1340, 0, 0, 40000, 186,0 }, + {1341,1341, 0, 0, 40000, 86,0 }, + {1342,1342, 0, 0, 7440, 2473,0 }, + {1343,1343, 0, 0, 40000, 160,0 }, + {1344,1344, 0, 0, 8966, 406,0 }, + {1345,1345, 0, 0, 40000, 1353,0 }, + {1346,1346, 0, 0, 14180, 4406,0 }, + { 378, 378, 84, 0, 1333, 460,0 }, + {1347,1347, 24, 0, 1893, 633,0 }, + {1348,1348, 44, 0, 206, 86,0 }, + {1349,1349, 40, 0, 586, 140,0 }, + {1350,1350, 60, 0, 1026, 320,0 }, + {1351,1351, 0, 0, 6560, 33,0 }, + {1352,1352, 0, 0, 7373, 2453,0 }, + {1353,1353, 0, 0, 4660, 1573,0 }, + {1354,1354, 0, 0, 40000, 346,0 }, + {1355,1355, 0, 0, 7126, 86,0 }, + {1356,1356, 0, 0, 40000, 213,0 }, + {1357,1357, 0, 0, 1180, 340,0 }, + {1358,1358, 0, 0, 3893, 1466,0 }, + {1359,1359, 0, 0, 2053, 1173,0 }, + {1360,1360, 0, 0, 40000, 200,0 }, + {1361,1361, 0, 0, 40000, 353,0 }, + {1362,1362, 0, 0, 40000, 273,0 }, + {1363,1363, 0, 0, 40000, 433,0 }, + {1364,1364, 0, 0, 1940, 426,0 }, + {1365,1365, 0, 0, 40000, 80,0 }, + {1366,1366, 0, 0, 40000, 106,0 }, + {1367,1367, 0, 0, 40000, 60,0 }, + {1368,1368, 0, 0, 40000, 140,0 }, + {1369,1369, 0, 0, 40000, 93,0 }, + {1370,1370, 0, 0, 40000, 73,0 }, + {1371,1371, 0, 0, 40000, 73,0 }, + {1372,1372, 0, 0, 40000, 93,0 }, + {1373,1373, 0, 0, 40000, 73,0 }, + {1374,1374, 0, 0, 40000, 80,0 }, + {1375,1375, 0, 0, 40000, 746,0 }, + {1376,1376, 0, 0, 2360, 813,0 }, + {1377,1377, 0, 0, 340, 146,0 }, + {1378,1378, 35, 0, 713, 273,0 }, + {1379,1379, 49, 0, 173, 93,0 }, + {1377,1377, 48, 0, 286, 126,0 }, + {1380,1380, 58, 0, 173, 100,0 }, + {1377,1377, 60, 0, 286, 133,0 }, + {1381,1381, 47, 0, 973, 360,0 }, + {1382,1382, 60, 0, 146, 86,0 }, + {1381,1381, 49, 0, 966, 333,0 }, + {1383,1383, 72, 0, 506, 206,0 }, + {1381,1381, 51, 0, 953, 340,0 }, + {1384,1384, 84, 0, 1340, 480,0 }, + {1381,1381, 54, 0, 986, 360,0 }, + {1381,1381, 57, 0, 980, 346,0 }, + {1385,1385, 72, 0, 1573, 440,0 }, + {1381,1381, 60, 0, 953, 340,0 }, + {1386,1386, 36, 0, 2673, 900,0 }, + {1387,1387, 93, 0, 233, 106,0 }, + {1388,1388, 72, 0, 966, 353,0 }, + {1389,1389, 84, 0, 1366, 473,0 }, + {1390,1390, 36, 0, 1326, 446,0 }, + {1391,1391, 64, 0, 220, 86,0 }, + {1392,1392, 68, 0, 126, 220,0 }, + {1393,1393, 0, 0, 4513, 640,0 }, + {1394,1394, 0, 0, 40000, 353,0 }, + {1395,1395, 0, 0, 40000, 73,0 }, + {1396,1396, 0, 0, 2040, 380,0 }, + {1397,1397, 0, 0, 40000, 240,0 }, + {1398,1398, 0, 0, 3246, 753,0 }, + {1399,1399, 0, 0, 40000, 66,0 }, + {1400,1400, 0, 0, 40000, 0,0 }, + {1401,1401, 0, 0, 40000, 0,0 }, + {1402,1402, 0, 0, 7720, 1260,0 }, + {1403,1403, 0, 0, 213, 6420,0 }, + {1404,1404, 0, 0, 40000, 66,0 }, + {1405,1405, 0, 0, 40000, 73,0 }, + {1406,1406, 0, 0, 40000, 93,0 }, + {1407,1407, 0, 0, 1606, 640,0 }, + {1408,1408, 0, 0, 15486, 1580,0 }, + {1409,1409, 0, 0, 40000, 353,0 }, + {1410,1410, 0, 0, 40000, 2066,0 }, + {1411,1411, 0, 0, 40000, 0,0 }, + {1412,1412, 0, 0, 15453, 73,0 }, + {1413,1413, 0, 0, 3726, 1240,0 }, + {1414,1414, 0, 0, 40000, 86,0 }, + {1415,1415, 0, 0, 40000, 200,0 }, + {1416,1416, 0, 0, 40000, 53,0 }, + {1417,1417, 0, 0, 40000, 73,0 }, + {1418,1418, 0, 0, 40000, 66,0 }, + {1419,1419, 0, 0, 40000, 26,0 }, + {1420,1420, 0, 0, 40000, 53,0 }, + {1421,1421, 0, 0, 40000, 40,0 }, + {1422,1422, 0, 0, 40000, 126,0 }, + {1423,1423, 0, 0, 40000, 0,0 }, + {1424,1424, 0, 0, 13653, 0,0 }, + {1425,1425, 0, 0, 12533, 1953,0 }, + {1426,1426, 0, 0, 973, 1280,0 }, + {1427,1427, 0, 0, 40000, 426,0 }, + {1428,1428, 0, 0, 40000, 53,0 }, + {1429,1429, 0, 0, 40000, 66,0 }, + {1430,1430, 0, 0, 526, 840,0 }, + {1431,1431, 0, 0, 286, 1293,0 }, + {1432,1432, 0, 0, 14726, 4920,0 }, + {1433,1433, 0, 0, 5233, 633,0 }, + {1434,1434, 0, 0, 13226, 2500,0 }, + { 740, 740, 0, 0, 513, 200,0 }, + {1435,1435, 0, 0, 40000, 5666,0 }, + { 739, 739, 48, 0, 213, 20,0 }, + { 500, 500, 55, 0, 100, 0,0 }, + { 740, 740, 60, 0, 226, 113,0 }, + { 500, 500, 41, 0, 106, 0,0 }, + {1436,1436, 84, 0, 160, 26,0 }, + {1437,1437, 84, 0, 386, 493,0 }, + { 500, 500, 48, 0, 100, 0,0 }, + {1438,1438, 15, 0, 340, 140,0 }, + { 752, 752, 49, 0, 173, 20,0 }, + {1438,1438, 16, 0, 346, 146,0 }, + {1438,1438, 12, 0, 340, 140,0 }, + { 740, 740, 55, 0, 220, 113,0 }, + { 752, 752, 18, 0, 206, 20,0 }, + { 752, 752, 15, 0, 200, 20,0 }, + { 752, 752, 17, 0, 206, 20,0 }, + {1439,1440, 0, 4, 40000, 0,0 }, + {1441,1442, 0, 4, 7360, 200,0 }, + {1443,1444, 0, 4, 11840, 320,0 }, + {1445,1446, 0, 4, 9920, 326,0 }, + {1447,1448, 0, 4, 10213, 0,0 }, + {1449,1450, 0, 4, 7440, 2486,0 }, + { 181,1451, 0, 4, 2360, 733,0 }, + {1452,1453, 0, 4, 9260, 240,0 }, + {1454,1455, 0, 4, 40000, 0,0 }, + {1456,1457, 0, 4, 660, 126,0 }, + {1458,1459, 0, 4, 40000, 66,0 }, + { 190,1460, 0, 4, 40000, 60,0 }, + { 192,1461, 0, 4, 40000, 73,0 }, + {1462,1463, 0, 4, 40000, 353,0 }, + {1464,1465, 0, 4, 40000, 353,0 }, + {1466,1467, 0, 4, 40000, 66,0 }, + {1468,1469, 0, 4, 40000, 46,0 }, + { 35,1470, 0, 4, 40000, 46,0 }, + { 36,1471, 0, 4, 320, 0,0 }, + {1472,1473, 0, 4, 320, 0,0 }, + {1474,1475, 0, 4, 7986, 93,0 }, + { 39,1476, 0, 4, 1053, 226,0 }, + {1477,1476, 0, 4, 1060, 226,0 }, + {1478,1479, 0, 4, 40000, 453,0 }, + { 50,1480, 0, 4, 40000, 400,0 }, + {1481,1482, 0, 4, 40000, 133,0 }, + {1483,1484, 0, 4, 40000, 0,0 }, + {1485,1486, 0, 4, 40000, 226,0 }, + { 55,1487, 0, 4, 40000, 100,0 }, + {1488,1489, 0, 4, 40000, 93,0 }, + {1490,1491, 0, 4, 40000, 73,0 }, + {1492,1493, 0, 4, 40000, 73,0 }, + {1494,1495, 0, 4, 40000, 73,0 }, + {1496,1497, 0, 4, 40000, 80,0 }, + {1496,1498, 0, 4, 40000, 73,0 }, + {1499,1500, 0, 4, 40000, 66,0 }, + {1501,1502, 0, 4, 40000, 146,0 }, + {1503,1504, 0, 4, 40000, 93,0 }, + {1505,1506, 0, 4, 40000, 73,0 }, + { 86,1507, 0, 4, 40000, 80,0 }, + {1508,1509, 0, 4, 40000, 0,0 }, + {1510,1511, 0, 4, 40000, 60,0 }, + {1512,1513, 0, 4, 40000, 0,0 }, + {1514,1515, 0, 4, 40000, 0,0 }, + {1516,1517, 0, 4, 40000, 773,0 }, + {1518,1519, 0, 4, 5346, 2973,0 }, + {1520,1521, 0, 4, 40000, 406,0 }, + {1522,1523, 0, 4, 9080, 360,0 }, + {1524,1525, 0, 4, 40000, 1200,0 }, + {1526,1527, 0, 4, 40000, 800,0 }, + {1528,1529, 0, 4, 40000, 960,0 }, + { 111,1530, 0, 4, 1200, 433,0 }, + {1531,1532, 0, 4, 226, 386,0 }, + { 115,1533, 0, 4, 2433, 0,0 }, + {1534,1535, 0, 4, 1873, 646,0 }, + {1536,1537, 0, 4, 3013, 53,0 }, + {1538,1539, 0, 4, 1560, 720,0 }, + {1540, 339, 0, 6, 6, 0,0 }, + {1541, 339, 0, 6, 6, 0,0 }, + {1542,1543, 0, 4, 993, 93,0 }, + {1544,1545, 0, 4, 293, 86,0 }, + {1546,1547, 0, 4, 40000, 153,0 }, + { 364, 365, 44, 4, 120, 0,0 }, + { 129,1548, 48, 4, 173, 0,0 }, + { 367, 368, 58, 4, 173, 0,0 }, + { 129,1549, 60, 4, 173, 0,0 }, + {1550,1551, 48, 4, 520, 200,0 }, + { 132,1552, 43, 4, 173, 0,0 }, + {1550,1551, 49, 4, 520, 200,0 }, + {1553,1554, 43, 4, 160, 80,0 }, + {1550,1551, 51, 4, 513, 0,0 }, + { 134,1555, 43, 4, 1733, 0,0 }, + {1550,1551, 54, 4, 506, 0,0 }, + {1550,1551, 57, 4, 506, 0,0 }, + { 380, 381, 72, 4, 1580, 0,0 }, + {1550,1551, 60, 4, 520, 0,0 }, + {1556,1557, 70, 4, 826, 306,0 }, + { 374, 375, 60, 4, 973, 0,0 }, + {1558,1559, 36, 4, 1233, 0,0 }, + {1560,1561, 65, 4, 293, 133,0 }, + {1562,1563, 84, 4, 1360, 0,0 }, + {1564,1565, 59, 4, 380, 0,0 }, + {1566,1567, 84, 4, 1593, 566,0 }, + {1568,1569, 35, 4, 1353, 473,0 }, + {1570,1571, 44, 4, 413, 0,0 }, + {1572,1573, 67, 4, 246, 0,0 }, + {1574,1575, 66, 4, 293, 0,0 }, + { 145,1576, 59, 4, 146, 0,0 }, + {1577,1578, 51, 4, 360, 0,0 }, + {1579,1580, 45, 4, 246, 0,0 }, + {1581,1582, 71, 4, 433, 0,0 }, + { 149,1583, 60, 4, 280, 0,0 }, + {1584,1585, 58, 4, 173, 0,0 }, + {1586,1587, 53, 4, 173, 0,0 }, + { 397,1588, 64, 4, 220, 80,0 }, + {1589,1590, 71, 4, 106, 53,0 }, + {1591,1592, 61, 4, 1000, 340,0 }, + {1593,1594, 61, 4, 1000, 340,0 }, + { 391, 392, 48, 4, 160, 46,0 }, + { 391, 393, 48, 4, 380, 60,0 }, + {1595,1596, 69, 4, 120, 0,0 }, + { 159,1597, 68, 4, 120, 0,0 }, + { 159,1597, 63, 4, 140, 0,0 }, + {1598,1599, 74, 4, 893, 273,0 }, + {1600,1601, 60, 4, 1013, 306,0 }, + {1602,1603, 80, 4, 220, 0,0 }, + {1604,1605, 64, 4, 1366, 0,0 }, + {1606,1607, 69, 4, 120, 73,0 }, + { 398, 399, 55, 4, 1540, 193,0 }, + {1608,1609, 75, 4, 1573, 0,0 }, + {1610,1611, 68, 4, 120, 0,0 }, + {1612,1613, 48, 4, 360, 0,0 }, + {1614,1615, 53, 4, 606, 0,0 }, + {1616,1616, 0, 0, 40000, 1586,0 }, + {1617,1617, 0, 0, 40000, 1226,0 }, + {1618,1618, 0, 0, 4546, 766,0 }, + {1619,1619, 0, 0, 40000, 420,0 }, + {1620,1620, 0, 0, 40000, 1573,0 }, + {1621,1621, 0, 0, 3326, 806,0 }, + {1622,1622, 0, 0, 40000, 746,0 }, + {1623,1623, 0, 0, 40000, 900,0 }, + {1624,1624, 0, 0, 12166, 1573,0 }, + {1625,1625, 0, 0, 40000, 80,0 }, + {1626,1626, 0, 0, 40000, 80,0 }, + {1627,1627, 0, 0, 40000, 80,0 }, + {1628,1628, 0, 0, 40000, 2713,0 }, + {1629,1629, 0, 0, 40000, 86,0 }, + {1630,1630, 0, 0, 40000, 80,0 }, + {1631,1631, 0, 0, 40000, 80,0 }, + {1632,1632, 0, 0, 40000, 813,0 }, + {1633,1633, 0, 0, 40000, 80,0 }, + {1634,1634, 0, 0, 40000, 80,0 }, + {1635,1635, 0, 0, 40000, 80,0 }, + {1636,1636, 0, 0, 40000, 193,0 }, + {1637,1637, 0, 0, 2920, 733,0 }, + {1638,1638, 0, 0, 40000, 373,0 }, + {1639,1639, 0, 0, 2286, 226,0 }, + {1640,1640, 0, 0, 40000, 226,0 }, + {1641,1641, 0, 0, 40000, 226,0 }, + {1642,1642, 0, 0, 40000, 433,0 }, + {1643,1643, 0, 0, 40000, 813,0 }, + {1644,1644, 0, 0, 40000, 80,0 }, + {1645,1645, 0, 0, 40000, 80,0 }, + {1646,1646, 0, 0, 40000, 80,0 }, + {1647,1647, 0, 0, 40000, 80,0 }, + {1648,1648, 0, 0, 40000, 80,0 }, + {1649,1649, 0, 0, 40000, 80,0 }, + {1650,1650, 0, 0, 40000, 146,0 }, + {1651,1651, 0, 0, 40000, 1280,0 }, + {1652,1652, 0, 0, 40000, 513,0 }, + {1653,1653, 0, 0, 40000, 313,0 }, + {1654,1654, 0, 0, 40000, 773,0 }, + {1655,1655, 0, 0, 7400, 2480,0 }, + {1656,1656, 0, 0, 3760, 1253,0 }, + {1657,1657, 0, 0, 40000, 380,0 }, + {1658,1658, 0, 0, 40000, 333,0 }, + {1659,1659, 0, 0, 40000, 2926,0 }, + {1660,1660, 0, 0, 40000, 5666,0 }, + {1661,1661, 0, 0, 40000, 1613,0 }, + {1662,1662, 0, 0, 3746, 1273,0 }, + {1663,1663, 0, 0, 13653, 0,0 }, + {1664,1664, 0, 0, 4640, 1553,0 }, + {1665,1665, 0, 0, 40000, 680,0 }, + {1666,1666, 0, 0, 6393, 426,0 }, + {1667,1667, 0, 0, 40000, 713,0 }, + {1668,1668, 12, 0, 166, 20,0 }, + {1669,1669, 48, 0, 460, 193,0 }, + { 736, 736, 52, 0, 286, 20,0 }, + {1670,1670, 48, 0, 506, 200,0 }, + {1670,1670, 36, 0, 713, 260,0 }, + { 377, 377, 84, 0, 386, 493,0 }, + { 730, 730, 95, 0, 1886, 653,0 }, + {1669,1669, 84, 0, 386, 166,0 }, + { 755, 755, 20, 0, 633, 240,0 }, + { 755, 755, 22, 0, 626, 240,0 }, + { 755, 755, 24, 0, 633, 246,0 }, + {1671,1671, 0, 0, 2233, 220,0 }, + {1672,1672, 0, 0, 2233, 240,0 }, + {1673,1673, 0, 0, 2233, 206,0 }, + {1674,1674, 0, 0, 2126, 173,0 }, + {1675,1675, 0, 0, 7473, 73,0 }, + {1676,1676, 0, 0, 40000, 0,0 }, + {1677,1677, 0, 0, 3493, 193,0 }, + {1678,1678, 0, 0, 1746, 73,0 }, + {1679,1679, 0, 0, 1013, 400,0 }, + {1680,1680, 0, 0, 3473, 1560,0 }, + {1681,1681, 0, 0, 1073, 40,0 }, + {1682,1682, 0, 0, 40000, 380,0 }, + {1683,1683, 0, 0, 1166, 400,0 }, + {1684,1684, 0, 0, 606, 146,0 }, + {1685,1685, 0, 0, 4553, 1486,0 }, + {1686,1686, 0, 0, 1126, 80,0 }, + {1687,1687, 0, 0, 40000, 73,0 }, + {1688,1688, 0, 0, 40000, 60,0 }, + {1689,1689, 0, 0, 40000, 66,0 }, + {1690,1690, 0, 0, 40000, 73,0 }, + {1691,1691, 0, 0, 40000, 73,0 }, + {1692,1692, 0, 0, 40000, 73,0 }, + {1693,1693, 0, 0, 40000, 73,0 }, + {1694,1694, 0, 0, 6380, 53,0 }, + {1695,1695, 0, 0, 6380, 60,0 }, + {1696,1696, 0, 0, 40000, 53,0 }, + {1697,1697, 0, 0, 40000, 0,0 }, + {1698,1698, 0, 0, 1880, 80,0 }, + {1699,1699, 0, 0, 40000, 60,0 }, + {1700,1700, 0, 0, 40000, 60,0 }, + {1701,1701, 0, 0, 1460, 80,0 }, + {1702,1702, 0, 0, 40000, 73,0 }, + {1703,1703, 0, 0, 40000, 0,0 }, + {1704,1704, 0, 0, 40000, 146,0 }, + {1705,1705, 0, 0, 40000, 66,0 }, + {1706,1706, 0, 0, 40000, 73,0 }, + {1707,1707, 0, 0, 40000, 160,0 }, + {1708,1708, 0, 0, 40000, 73,0 }, + {1709,1709, 0, 0, 40000, 193,0 }, + {1710,1710, 0, 0, 3740, 1260,0 }, + {1711,1711, 0, 0, 40000, 180,0 }, + {1712,1712, 0, 0, 40000, 173,0 }, + {1713,1713, 0, 0, 40000, 113,0 }, + {1714,1714, 0, 0, 40000, 86,0 }, + {1715,1715, 0, 0, 1853, 633,0 }, + {1716,1716, 0, 0, 40000, 0,0 }, + {1717,1717, 0, 0, 1066, 306,0 }, + {1718,1718, 0, 0, 40000, 86,0 }, + {1719,1719, 0, 0, 40000, 586,0 }, + {1720,1720, 0, 0, 40000, 86,0 }, + {1721,1721, 0, 0, 40000, 93,0 }, + {1722,1722, 0, 0, 40000, 373,0 }, + {1723,1723, 0, 0, 40000, 113,0 }, + {1724,1724, 0, 0, 40000, 353,0 }, + {1725,1725, 0, 0, 420, 73,0 }, + {1726,1726, 0, 0, 40000, 66,0 }, + {1727,1727, 0, 0, 40000, 53,0 }, + {1728,1728, 0, 0, 40000, 66,0 }, + {1729,1729, 0, 0, 40000, 100,0 }, + {1730,1730, 0, 0, 40000, 93,0 }, + {1731,1731, 0, 0, 40000, 0,0 }, + {1732,1732, 0, 0, 40000, 73,0 }, + {1733,1733, 0, 0, 40000, 80,0 }, + {1734,1734, 0, 0, 40000, 80,0 }, + {1735,1735, 0, 0, 40000, 80,0 }, + {1736,1736, 0, 0, 40000, 80,0 }, + {1737,1737, 0, 0, 40000, 80,0 }, + {1738,1738, 0, 0, 40000, 73,0 }, + {1739,1739, 0, 0, 40000, 73,0 }, + {1740,1740, 0, 0, 40000, 106,0 }, + {1741,1741, 0, 0, 40000, 73,0 }, + {1742,1742, 0, 0, 40000, 73,0 }, + {1743,1743, 0, 0, 40000, 80,0 }, + {1744,1744, 0, 0, 40000, 0,0 }, + {1745,1745, 0, 0, 40000, 80,0 }, + {1746,1746, 0, 0, 40000, 66,0 }, + {1747,1747, 0, 0, 40000, 73,0 }, + {1748,1748, 0, 0, 40000, 0,0 }, + {1749,1749, 0, 0, 40000, 80,0 }, + {1750,1750, 0, 0, 40000, 66,0 }, + {1751,1751, 0, 0, 40000, 73,0 }, + {1752,1752, 0, 0, 40000, 80,0 }, + {1753,1753, 0, 0, 40000, 33,0 }, + {1754,1754, 0, 0, 40000, 0,0 }, + {1755,1755, 0, 0, 40000, 266,0 }, + {1756,1756, 0, 0, 40000, 160,0 }, + {1757,1757, 0, 0, 40000, 93,0 }, + {1758,1758, 0, 0, 40000, 660,0 }, + {1759,1759, 0, 0, 40000, 1453,0 }, + {1760,1760, 0, 0, 40000, 660,0 }, + {1761,1761, 0, 0, 40000, 120,0 }, + {1762,1762, 0, 0, 40000, 140,0 }, + {1763,1763, 0, 0, 9820, 393,0 }, + {1764,1764, 0, 0, 40000, 73,0 }, + {1765,1765, 0, 0, 3620, 1166,0 }, + {1766,1766, 0, 0, 40000, 0,0 }, + {1767,1767, 0, 0, 40000, 0,0 }, + {1768,1768, 0, 0, 40000, 813,0 }, + {1769,1769, 0, 0, 40000, 0,0 }, + {1770,1770, 0, 0, 40000, 2386,0 }, + {1771,1771, 0, 0, 4380, 400,0 }, + {1772,1772, 0, 0, 853, 0,0 }, + {1773,1773, 0, 0, 3700, 93,0 }, + {1774,1774, 0, 0, 1580, 300,0 }, + {1775,1775, 0, 0, 453, 140,0 }, + {1776,1776, 0, 0, 40000, 66,0 }, + {1777,1777, 0, 0, 40000, 73,0 }, + {1778,1778, 0, 0, 40000, 206,0 }, + {1779,1779, 0, 0, 4646, 1560,0 }, + {1780,1780, 0, 0, 353, 146,0 }, + {1781,1781, 0, 0, 1300, 400,0 }, + {1782,1782, 0, 0, 4593, 1546,0 }, + {1783,1783, 0, 0, 613, 226,0 }, + {1784,1784, 0, 0, 626, 233,0 }, + {1785,1785, 0, 0, 3020, 66,0 }, + {1786,1786, 0, 0, 1093, 186,0 }, + {1787,1787, 0, 0, 6053, 1240,0 }, + {1788,1788, 0, 0, 633, 126,0 }, + {1789,1789, 0, 0, 40000, 66,0 }, + {1790,1790, 0, 0, 40000, 73,0 }, + {1791,1791, 0, 0, 40000, 1253,0 }, + {1792,1792, 0, 0, 626, 246,0 }, + {1793,1793, 48, 0, 293, 120,0 }, + {1794,1794, 48, 0, 100, 0,0 }, + {1795,1795, 60, 0, 240, 133,0 }, + {1796,1796, 60, 0, 160, 66,0 }, + {1797,1797, 70, 0, 140, 33,0 }, + {1798,1798, 51, 0, 526, 206,0 }, + {1799,1799, 60, 0, 173, 93,0 }, + {1798,1798, 54, 0, 520, 200,0 }, + {1800,1800, 60, 0, 153, 80,0 }, + {1798,1798, 56, 0, 520, 206,0 }, + {1801,1801, 60, 0, 673, 206,0 }, + {1798,1798, 61, 0, 506, 200,0 }, + {1798,1798, 63, 0, 513, 206,0 }, + {1802,1802, 48, 0, 673, 200,0 }, + {1798,1798, 68, 0, 440, 180,0 }, + {1803,1803, 60, 0, 1873, 653,0 }, + {1804,1804, 60, 0, 673, 200,0 }, + {1805,1805, 66, 0, 306, 120,0 }, + {1806,1806, 60, 0, 673, 200,0 }, + { 379, 379, 59, 0, 173, 93,0 }, + {1802,1802, 64, 0, 673, 206,0 }, + {1807,1807, 48, 0, 1006, 20,0 }, + {1808,1808, 56, 0, 120, 40,0 }, + {1809,1809, 53, 0, 286, 133,0 }, + {1810,1810, 65, 0, 106, 0,0 }, + {1811,1811, 49, 0, 293, 133,0 }, + {1811,1811, 43, 0, 293, 133,0 }, + { 386, 386, 65, 0, 1013, 673,0 }, + { 386, 386, 60, 0, 1000, 660,0 }, + {1812,1812, 70, 0, 260, 113,0 }, + {1812,1812, 65, 0, 306, 120,0 }, + {1813,1813, 60, 0, 246, 106,0 }, + {1814,1814, 60, 0, 193, 120,0 }, + {1815,1815, 56, 0, 206, 13,0 }, + {1816,1816, 53, 0, 433, 73,0 }, + {1817,1817, 60, 0, 220, 113,0 }, + {1818,1818, 48, 0, 300, 66,0 }, + {1819,1819, 69, 0, 126, 0,0 }, + { 328, 328, 67, 0, 140, 93,0 }, + { 328, 328, 62, 0, 153, 100,0 }, + {1820,1820, 65, 0, 433, 100,0 }, + {1821,1821, 60, 0, 426, 100,0 }, + {1822,1822, 63, 0, 113, 46,0 }, + {1823,1823, 63, 0, 1866, 653,0 }, + {1824,1824, 67, 0, 273, 60,0 }, + {1825,1825, 60, 0, 973, 360,0 }, + {1825,1825, 72, 0, 806, 273,0 }, + { 401, 401, 62, 0, 46, 0,0 }, + {1826,1826, 48, 0, 126, 66,0 }, + {1827,1827, 53, 0, 980, 353,0 }, + {1828,1828, 60, 0, 293, 133,0 }, + {1829,1829, 60, 0, 160, 20,0 }, + {1830,1830, 60, 0, 126, 86,0 }, + {1831,1831, 60, 0, 173, 93,0 }, + {1832,1832, 0, 0, 40000, 106,0 }, + {1833,1833, 0, 0, 3780, 73,0 }, + {1834,1834, 0, 0, 3820, 1666,0 }, + {1835,1835, 0, 0, 40000, 73,0 }, + {1836,1836, 0, 0, 40000, 333,0 }, + {1837,1837, 0, 0, 40000, 220,0 }, + {1838,1838, 0, 0, 40000, 0,0 }, + {1839,1839, 0, 0, 40000, 53,0 }, + {1840,1840, 0, 0, 40000, 60,0 }, + {1841,1841, 0, 0, 5913, 2306,0 }, + {1842,1842, 0, 0, 7713, 2466,0 }, + { 525, 525, 0, 0, 4660, 660,0 }, + {1843,1843, 0, 0, 40000, 313,0 }, + {1844,1844, 0, 0, 40000, 0,0 }, + {1845,1845, 0, 0, 40000, 0,0 }, + {1846,1846, 0, 0, 1246, 453,0 }, + {1847,1847, 0, 0, 9600, 1580,0 }, + {1848,1848, 0, 0, 40000, 106,0 }, + {1849,1849, 0, 0, 2040, 400,0 }, + {1850,1850, 0, 0, 40000, 73,0 }, + {1851,1851, 0, 0, 4220, 620,0 }, + {1852,1852, 0, 0, 40000, 0,0 }, + {1853,1853, 0, 0, 40000, 433,0 }, + {1854,1854, 0, 0, 40000, 66,0 }, + {1855,1855, 0, 0, 40000, 46,0 }, + {1856,1856, 0, 0, 40000, 240,0 }, + {1857,1857, 0, 0, 40000, 313,0 }, + {1858,1858, 0, 0, 40000, 26,0 }, + {1859,1859, 0, 0, 40000, 0,0 }, + {1860,1860, 0, 0, 40000, 73,0 }, + {1861,1861, 0, 0, 6940, 66,0 }, + {1862,1862, 0, 0, 40000, 0,0 }, + {1863,1863, 0, 0, 40000, 60,0 }, + {1864,1864, 0, 0, 8140, 1440,0 }, + {1865,1865, 0, 0, 40000, 0,0 }, + {1866,1866, 0, 0, 40000, 613,0 }, + {1867,1867, 0, 0, 40000, 0,0 }, + {1868,1868, 0, 0, 633, 233,0 }, + {1869,1869, 0, 0, 40000, 226,0 }, + {1870,1870, 0, 0, 2280, 746,0 }, + {1871,1871, 0, 0, 1940, 633,0 }, + {1872,1872, 0, 0, 4220, 620,0 }, + {1873,1873, 0, 0, 40000, 133,0 }, + {1874,1874, 41, 0, 380, 153,0 }, + {1875,1875, 70, 0, 106, 0,0 }, + {1876,1876, 60, 0, 380, 206,0 }, + {1877,1877, 80, 0, 100, 0,0 }, + {1878,1878, 84, 0, 120, 0,0 }, + {1879,1879, 72, 0, 500, 433,0 }, + {1880,1880, 84, 0, 860, 553,0 }, + { 128, 128, 70, 0, 106, 0,0 }, + { 132, 132, 60, 0, 146, 86,0 }, + {1881,1882, 0, 4, 40000, 260,0 }, + {1883,1883, 0, 0, 40000, 0,0 }, + {1884,1885, 0, 4, 40000, 73,0 }, + {1886,1887, 0, 4, 40000, 86,0 }, + {1888,1889, 0, 4, 40000, 73,0 }, + {1890,1890, 0, 0, 40000, 300,0 }, + {1891,1891, 0, 0, 40000, 693,0 }, + {1892,1892, 0, 0, 40000, 586,0 }, + {1893,1893, 0, 0, 40000, 286,0 }, + {1894,1894, 0, 0, 1620, 773,0 }, + {1895,1895, 0, 0, 40000, 0,0 }, + {1896,1896, 0, 0, 40000, 193,0 }, + {1897,1897, 0, 0, 1873, 820,0 }, + {1898,1898, 0, 0, 4520, 753,0 }, + {1899,1899, 0, 0, 40000, 0,0 }, + {1900,1900, 0, 0, 40000, 220,0 }, + {1901,1901, 0, 0, 40000, 133,0 }, + {1902,1902, 0, 0, 40000, 73,0 }, + {1903,1903, 0, 0, 40000, 0,0 }, + {1904,1904, 0, 0, 7326, 2420,0 }, + {1905,1905, 0, 0, 1186, 446,0 }, + {1906,1906, 0, 0, 40000, 553,0 }, + {1907,1907, 0, 0, 40000, 293,0 }, + {1908,1908, 0, 0, 40000, 586,0 }, + {1909,1909, 0, 0, 2326, 793,0 }, + { 501, 501, 0, 0, 480, 226,0 }, + {1910,1910, 0, 0, 40000, 93,0 }, + {1911,1911, 0, 0, 620, 226,0 }, + {1912,1912, 0, 0, 2373, 800,0 }, + {1913,1913, 0, 0, 40000, 4986,0 }, + {1914,1914, 0, 0, 626, 240,0 }, + { 511, 511, 0, 0, 2326, 800,0 }, + {1915,1915, 0, 0, 340, 146,0 }, + {1910,1910, 60, 0, 40000, 93,0 }, + { 511, 511, 72, 0, 1566, 546,0 }, + {1915,1915, 84, 0, 246, 120,0 }, + {1916,1916, 0, 0, 40000, 0,0 }, + {1917,1917, 0, 0, 2713, 666,0 }, + {1918,1918, 0, 0, 40000, 0,0 }, + {1919,1919, 0, 0, 40000, 46,0 }, + {1920,1920, 0, 0, 40000, 0,0 }, + {1921,1921, 0, 0, 40000, 53,0 }, + {1922,1922, 0, 0, 40000, 33,0 }, + {1923,1923, 0, 0, 2073, 193,0 }, + {1924,1924, 0, 0, 40000, 146,0 }, + {1925,1925, 0, 0, 40000, 100,0 }, + {1926,1926, 0, 0, 40000, 93,0 }, + {1927,1927, 0, 0, 40000, 73,0 }, + {1928,1928, 0, 0, 40000, 540,0 }, + {1929,1929, 0, 0, 40000, 520,0 }, + {1930,1930, 0, 0, 40000, 506,0 }, + {1931,1931, 0, 0, 7406, 200,0 }, + {1932,1932, 0, 0, 5906, 133,0 }, + {1933,1933, 0, 0, 7426, 240,0 }, + {1934,1934, 0, 0, 7426, 240,0 }, + {1935,1935, 0, 0, 40000, 66,0 }, + {1936,1936, 0, 0, 40000, 66,0 }, + {1937,1937, 0, 0, 40000, 53,0 }, + {1938,1938, 0, 0, 40000, 66,0 }, + {1939,1939, 0, 0, 40000, 66,0 }, + {1940,1940, 0, 0, 40000, 53,0 }, + {1941,1941, 0, 0, 40000, 2146,0 }, + {1942,1942, 0, 0, 40000, 1126,0 }, + {1943,1943, 0, 0, 40000, 1020,0 }, + {1944,1944, 0, 0, 40000, 433,0 }, + {1945,1945, 0, 0, 40000, 0,0 }, + {1946,1946, 0, 0, 40000, 140,0 }, + {1947,1947, 0, 0, 4660, 660,0 }, + {1948,1948, 0, 0, 40000, 66,0 }, + {1949,1949, 0, 0, 40000, 4193,0 }, + {1950,1950, 0, 0, 7713, 2466,0 }, + {1951,1951, 0, 0, 40000, 73,0 }, + {1952,1952, 0, 0, 8100, 2093,0 }, + {1953,1953, 0, 0, 40000, 86,0 }, + {1954,1954, 0, 0, 40000, 80,0 }, + {1955,1955, 0, 0, 4113, 1526,0 }, + {1956,1956, 0, 0, 40000, 66,0 }, + {1957,1957, 0, 0, 40000, 100,0 }, + {1958,1958, 0, 0, 40000, 213,0 }, + {1959,1959, 0, 0, 40000, 100,0 }, + {1960,1960, 0, 0, 1186, 100,0 }, + {1961,1961, 0, 0, 40000, 433,0 }, + {1962,1962, 0, 0, 40000, 146,0 }, + {1963,1963, 0, 0, 40000, 400,0 }, + {1964,1964, 0, 0, 40000, 66,0 }, + {1965,1965, 0, 0, 40000, 193,0 }, + {1966,1966, 0, 0, 1153, 100,0 }, + {1967,1967, 0, 0, 4800, 1400,0 }, + {1968,1968, 0, 0, 2906, 713,0 }, + {1969,1969, 0, 0, 40000, 73,0 }, + {1970,1970, 0, 0, 2280, 746,0 }, + {1971,1971, 0, 0, 40000, 66,0 }, + {1972,1972, 0, 0, 40000, 86,0 }, + {1973,1973, 0, 0, 40000, 86,0 }, + {1974,1974, 0, 0, 40000, 66,0 }, + {1975,1975, 0, 0, 40000, 66,0 }, + {1976,1976, 0, 0, 40000, 66,0 }, + {1977,1977, 0, 0, 40000, 46,0 }, + {1978,1978, 0, 0, 40000, 73,0 }, + {1979,1979, 0, 0, 40000, 73,0 }, + {1980,1980, 0, 0, 40000, 66,0 }, + {1981,1981, 0, 0, 40000, 66,0 }, + {1982,1982, 0, 0, 40000, 66,0 }, + {1983,1983, 0, 0, 40000, 73,0 }, + {1984,1984, 0, 0, 40000, 73,0 }, + {1985,1985, 0, 0, 40000, 253,0 }, + {1986,1986, 0, 0, 40000, 126,0 }, + {1987,1987, 0, 0, 40000, 126,0 }, + {1988,1988, 0, 0, 40000, 66,0 }, + {1989,1989, 0, 0, 40000, 66,0 }, + {1990,1990, 0, 0, 40000, 53,0 }, + {1991,1991, 0, 0, 40000, 140,0 }, + {1992,1992, 0, 0, 40000, 40,0 }, + {1993,1993, 0, 0, 40000, 73,0 }, + {1994,1994, 0, 0, 40000, 66,0 }, + {1995,1995, 0, 0, 40000, 73,0 }, + {1996,1996, 0, 0, 40000, 73,0 }, + {1997,1997, 0, 0, 40000, 73,0 }, + {1998,1998, 0, 0, 40000, 73,0 }, + {1999,1999, 0, 0, 40000, 66,0 }, + {2000,2000, 0, 0, 40000, 433,0 }, + {2001,2001, 0, 0, 40000, 433,0 }, + {2002,2002, 0, 0, 2440, 706,0 }, + {2003,2003, 0, 0, 13960, 4800,0 }, + {2004,2004, 0, 0, 7393, 2480,0 }, + {2005,2005, 0, 0, 7220, 2073,0 }, + {2006,2006, 0, 0, 633, 233,0 }, + {2007,2007, 0, 0, 2326, 780,0 }, + {2008,2008, 0, 0, 40000, 73,0 }, + {2009,2009, 0, 0, 40000, 106,0 }, + {2010,2010, 0, 0, 40000, 126,0 }, + {2011,2011, 0, 0, 40000, 386,0 }, + {2012,2012, 0, 0, 40000, 66,0 }, + {2013,2013, 0, 0, 6893, 1273,0 }, + {2014,2014, 0, 0, 2546, 633,0 }, + {2015,2015, 0, 0, 206, 106,0 }, + {2016,2016, 0, 0, 213, 113,0 }, + {2017,2017, 0, 0, 360, 140,0 }, + {2018,2018, 0, 0, 1013, 193,0 }, + {2019,2019, 0, 0, 266, 66,0 }, + {2020,2020, 0, 0, 1880, 660,0 }, + {2021,2021, 0, 0, 286, 206,0 }, + {2022,2022, 0, 0, 3706, 1353,0 }, + {2023,2023, 0, 0, 1106, 380,0 }, + {2024,2024, 0, 0, 13220, 2466,0 }, + {2025,2025, 0, 0, 333, 26,0 }, + {2026,2026, 0, 0, 7346, 2440,0 }, + {2027,2027, 0, 0, 1273, 453,0 }, + { 352, 352, 51, 2, 6, 0,0 }, + {2028,2028, 35, 0, 700, 253,0 }, + {2028,2028, 36, 0, 706, 266,0 }, + {2029,2029, 47, 0, 100, 0,0 }, + {2030,2030, 38, 0, 346, 140,0 }, + {2019,2019, 39, 0, 220, 106,0 }, + {2031,2031, 45, 0, 286, 133,0 }, + { 492, 492, 41, 0, 1040, 406,0 }, + {2032,2032, 42, 0, 220, 106,0 }, + {2033,2033, 44, 0, 500, 193,0 }, + { 492, 492, 48, 0, 833, 346,0 }, + {2034,2034, 46, 0, 1866, 646,0 }, + { 492, 492, 53, 0, 873, 386,0 }, + { 167, 167, 56, 0, 646, 353,0 }, + {2035,2035, 61, 0, 366, 146,0 }, + {2036,2036, 56, 0, 1346, 473,0 }, + {2037,2037, 60, 0, 213, 126,0 }, + { 144, 144, 59, 0, 213, 0,0 }, + {2038,2038, 59, 0, 106, 0,0 }, + { 169, 169, 51, 0, 380, 366,0 }, + { 169, 169, 45, 0, 380, 366,0 }, + {2039,2039, 72, 0, 246, 20,0 }, + {2040,2040, 60, 0, 280, 20,0 }, + {2041,2041, 58, 0, 373, 360,0 }, + {2042,2042, 53, 0, 380, 366,0 }, + {2043,2043, 73, 0, 120, 26,0 }, + { 158, 158, 75, 0, 126, 140,0 }, + {2044,2044, 0, 0, 6786, 1073,0 }, + {2045,2045, 0, 0, 2046, 473,0 }, + {2046,2046, 0, 0, 3746, 1273,0 }, + {2047,2047, 0, 0, 1200, 3086,0 }, + {2048,2048, 0, 0, 1200, 3080,0 }, + {2049,2049, 0, 0, 40000, 2453,0 }, + {2050,2050, 0, 0, 40000, 413,0 }, + {2051,2051, 0, 0, 980, 2553,0 }, + {2052,2052, 0, 0, 40000, 2420,0 }, + {2053,2053, 0, 0, 40000, 2506,0 }, + {2054,2054, 0, 0, 40000, 380,0 }, + {2055,2055, 0, 0, 40000, 660,0 }, + {2056,2056, 0, 0, 40000, 73,0 }, + {2057,2057, 0, 0, 40000, 333,0 }, + {2058,2058, 0, 0, 833, 146,0 }, + {2059,2059, 0, 0, 1686, 620,0 }, + {2060,2060, 0, 0, 40000, 73,0 }, + {2061,2061, 0, 0, 40000, 0,0 }, + {2062,2062, 0, 0, 1873, 633,0 }, + {2063,2063, 0, 0, 40000, 380,0 }, + {2064,2064, 0, 0, 366, 286,0 }, + {2065,2065, 0, 0, 8866, 1366,0 }, + {2066,2066, 0, 0, 40000, 1513,0 }, + {2067,2067, 0, 0, 40000, 333,0 }, + {2068,2068, 0, 0, 9600, 1573,0 }, + {2069,2069, 0, 0, 3293, 746,0 }, + {2070,2070, 0, 0, 40000, 53,0 }, + {2071,2071, 0, 0, 40000, 73,0 }, + {2072,2072, 0, 0, 40000, 73,0 }, + {2073,2073, 0, 0, 40000, 240,0 }, + {2074,2074, 0, 0, 40000, 240,0 }, + {2075,2075, 0, 0, 40000, 140,0 }, + {2076,2076, 0, 0, 40000, 113,0 }, + {2077,2077, 0, 0, 40000, 240,0 }, + {2078,2078, 0, 0, 3613, 1146,0 }, + {2079,2079, 0, 0, 40000, 126,0 }, + {2080,2080, 0, 0, 40000, 0,0 }, + {2081,2081, 0, 0, 40000, 633,0 }, + {2082,2082, 0, 0, 40000, 453,0 }, + {2083,2083, 0, 0, 40000, 1146,0 }, + {2084,2084, 0, 0, 40000, 3600,0 }, + {2085,2085, 0, 0, 40000, 1586,0 }, + {2086,2086, 0, 0, 40000, 1586,0 }, + {2087,2087, 0, 0, 40000, 1586,0 }, + {2088,2088, 0, 0, 40000, 1646,0 }, + {2089,2089, 0, 0, 40000, 1580,0 }, + {2090,2090, 0, 0, 40000, 4393,0 }, + {2091,2091, 0, 0, 40000, 4540,0 }, + {2092,2092, 0, 0, 21373, 6160,0 }, + {2093,2093, 0, 0, 40000, 633,0 }, + {2094,2094, 0, 0, 18420, 6146,0 }, + {2095,2095, 0, 0, 2306, 813,0 }, + {2096,2096, 0, 0, 2813, 333,0 }, + {2097,2097, 0, 0, 3106, 600,0 }, + {2098,2098, 0, 0, 1026, 1580,0 }, + {2099,2099, 0, 0, 1873, 346,0 }, + {2100,2100, 0, 0, 40000, 73,0 }, + {2101,2101, 0, 0, 40000, 73,0 }, + {2102,2102, 0, 0, 1200, 1906,0 }, + {2103,2103, 0, 0, 980, 1313,0 }, + {2104,2104, 0, 0, 200, 20,0 }, + {2105,2105, 0, 0, 640, 253,0 }, + {2106,2106, 0, 0, 3120, 240,0 }, + {2107,2107, 0, 0, 753, 146,0 }, + {2108,2108, 0, 0, 40000, 3060,0 }, + {2109,2109, 0, 0, 40000, 233,0 }, + {2110,2110, 0, 0, 40000, 246,0 }, + {2111,2111, 0, 0, 40000, 240,0 }, + { 752, 752, 60, 0, 173, 20,0 }, + { 755, 755, 12, 0, 626, 240,0 }, + {2112,2112, 89, 0, 113, 0,0 }, + {2113,2113, 89, 0, 700, 266,0 }, + { 755, 755, 14, 0, 626, 240,0 }, + { 755, 755, 16, 0, 626, 246,0 }, + {2114,2114, 84, 0, 1593, 553,0 }, + { 755, 755, 19, 0, 626, 240,0 }, + {2115,2115, 38, 0, 220, 166,0 }, + {2116,2116, 36, 0, 1686, 760,0 }, + { 755, 755, 28, 0, 626, 240,0 }, + { 755, 755, 26, 0, 626, 240,0 }, + { 755, 755, 35, 0, 633, 246,0 }, + { 755, 755, 30, 0, 626, 240,0 }, + {2117,2117, 60, 0, 180, 53,0 }, + {2104,2104, 60, 0, 173, 20,0 }, + {2104,2104, 55, 0, 173, 20,0 }, + { 730, 730, 94, 0, 1886, 660,0 }, + {2118,2118, 0, 0, 1226, 73,0 }, + {2119,2119, 0, 0, 40000, 0,0 }, + {2120,2120, 0, 0, 40000, 146,0 }, + {2121,2121, 0, 0, 40000, 80,0 }, + {2122,2122, 0, 0, 40000, 80,0 }, + {2123,2123, 0, 0, 40000, 0,0 }, + {2124,2124, 0, 0, 40000, 126,0 }, + {2125,2125, 0, 0, 40000, 213,0 }, + {2126,2126, 0, 0, 40000, 80,0 }, + {2127,2127, 0, 0, 40000, 73,0 }, + {2128,2128, 0, 0, 40000, 73,0 }, + {2129,2129, 0, 0, 40000, 73,0 }, + {2130,2130, 0, 0, 40000, 80,0 }, + {2131,2131, 0, 0, 40000, 73,0 }, + {2132,2132, 0, 0, 40000, 73,0 }, + {2133,2133, 0, 0, 40000, 66,0 }, + {2134,2134, 0, 0, 40000, 186,0 }, + {2135,2135, 0, 0, 9966, 426,0 }, + {2136,2136, 0, 0, 40000, 400,0 }, + {2137,2137, 0, 0, 40000, 326,0 }, + {2138,2138, 0, 0, 386, 80,0 }, + {2139,2139, 0, 0, 40000, 246,0 }, + {2140,2140, 0, 0, 3473, 73,0 }, + {2141,2141, 60, 0, 160, 66,0 }, + {2141,2141, 44, 0, 160, 60,0 }, + {2142,2142, 47, 0, 173, 93,0 }, + {2143,2143, 47, 0, 186, 80,0 }, + {2144,2144, 62, 0, 1933, 93,0 }, + {2145,2145, 93, 0, 1146, 473,0 }, + {2146,2146, 50, 0, 286, 93,0 }, + {2145,2145, 40, 0, 2013, 840,0 }, + {2147,2147, 60, 0, 106, 73,0 }, + { 898, 898, 60, 0, 173, 133,0 }, + {2147,2147, 57, 0, 106, 73,0 }, + { 900, 900, 42, 0, 620, 240,0 }, + { 900, 900, 38, 0, 626, 240,0 }, + { 908, 908, 88, 0, 160, 26,0 }, + {2148,2148, 0, 0, 9440, 140,0 }, + {2149,2149, 0, 0, 40000, 73,0 }, + {2150,2150, 0, 0, 4613, 420,0 }, + {2151,2151, 0, 0, 40000, 86,0 }, + {2152,2152, 0, 0, 40000, 406,0 }, + {2153,2153, 0, 0, 40000, 440,0 }, + {2154,2154, 0, 0, 4340, 133,0 }, + {2155,2155, 0, 0, 4460, 706,0 }, + {2156,2156, 0, 0, 40000, 73,0 }, + {2157,2157, 0, 0, 4660, 1573,0 }, + {2158,2158, 0, 0, 966, 333,0 }, + {2159,2159, 0, 0, 1933, 640,0 }, + { 136, 136, 0, 0, 2326, 786,0 }, + { 168, 168, 0, 0, 286, 366,0 }, + { 164, 164, 0, 0, 7373, 2460,0 }, + { 167, 167, 0, 0, 793, 426,0 }, + {2160,2160, 65, 0, 166, 73,0 }, + {2161,2161, 21, 0, 480, 146,0 }, + {2162, 173, 0, 4, 4220, 80,0 }, + {2163,2164, 0, 4, 4640, 3066,0 }, + {2165,2166, 0, 4, 7273, 3920,0 }, + {2167,2168, 0, 4, 3766, 1253,0 }, + {2169,2170, 0, 4, 6266, 2400,0 }, + {2171,2172, 0, 4, 18213, 0,0 }, + {2173,2174, 0, 4, 40000, 713,0 }, + {2175,2174, 0, 4, 40000, 733,0 }, + {2176, 299, 0, 4, 40000, 273,0 }, + {2177,2178, 0, 4, 40000, 66,0 }, + {2179,2180, 0, 4, 40000, 393,0 }, + {2181,2182, 0, 4, 40000, 413,0 }, + {2183,2184, 0, 4, 7406, 200,0 }, + { 127, 127, 65, 0, 226, 120,0 }, + { 127, 127, 72, 0, 180, 100,0 }, + { 364, 365, 52, 4, 120, 0,0 }, + {2185,2186, 60, 4, 173, 0,0 }, + {1550,1551, 47, 4, 520, 0,0 }, + {1556,1557, 76, 4, 833, 0,0 }, + { 374, 375, 84, 4, 813, 0,0 }, + {1564,1565, 83, 4, 220, 0,0 }, + {1568,1569, 24, 4, 1840, 620,0 }, + {1556,1557, 77, 4, 820, 300,0 }, + {1572,1573, 60, 4, 286, 0,0 }, + {1574,1575, 65, 4, 293, 0,0 }, + { 391, 392, 44, 4, 160, 53,0 }, + { 391, 393, 40, 4, 460, 66,0 }, + {1606,1607, 72, 4, 120, 73,0 }, + { 398, 399, 73, 4, 1293, 173,0 }, + {1608,1609, 70, 4, 1580, 0,0 }, + {2187,2187, 0, 0, 40000, 353,0 }, + {2188,2188, 0, 0, 40000, 333,0 }, + {2189,2189, 0, 0, 5913, 2306,0 }, + {2190,2190, 0, 0, 7720, 1260,0 }, + {2191,2191, 0, 0, 213, 6420,0 }, + {2192,2192, 0, 0, 40000, 380,0 }, + {2193,2193, 0, 0, 1153, 760,0 }, + {2194,2194, 0, 0, 40000, 66,0 }, + {2195,2195, 0, 0, 4440, 66,0 }, + {2196,2196, 0, 0, 40000, 73,0 }, + {2197,2197, 0, 0, 40000, 53,0 }, + {2198,2198, 0, 0, 40000, 60,0 }, + {2199,2199, 0, 0, 40000, 60,0 }, + {2200,2200, 0, 0, 8133, 1433,0 }, + { 528, 528, 0, 0, 966, 346,0 }, + {2201,2201, 0, 0, 40000, 126,0 }, + {2202,2202, 0, 0, 286, 1293,0 }, + {2203,2203, 0, 0, 40000, 0,0 }, + {2204,2204, 41, 0, 246, 20,0 }, + {2205,2205, 84, 0, 160, 26,0 }, + {2206,2206, 72, 0, 440, 180,0 }, + { 741, 741, 48, 0, 220, 26,0 }, + {2207,2207, 0, 0, 2126, 173,0 }, + {2208,2208, 0, 0, 40000, 0,0 }, + {2209,2209, 0, 0, 40000, 380,0 }, + {2210,2210, 0, 0, 4553, 1486,0 }, + {2211,2211, 0, 0, 40000, 73,0 }, + {2212,2212, 0, 0, 40000, 73,0 }, + {2213,2213, 0, 0, 1460, 80,0 }, + {2214,2214, 0, 0, 40000, 66,0 }, + {2215,2215, 0, 0, 40000, 186,0 }, + {2216,2216, 0, 0, 40000, 180,0 }, + {2217,2217, 0, 0, 40000, 173,0 }, + {2218,2218, 0, 0, 40000, 113,0 }, + {2219,2219, 0, 0, 40000, 86,0 }, + {2220,2220, 0, 0, 40000, 373,0 }, + {2221,2221, 0, 0, 40000, 113,0 }, + {2222,2222, 0, 0, 40000, 353,0 }, + {2223,2223, 0, 0, 40000, 66,0 }, + {2224,2224, 0, 0, 40000, 53,0 }, + {2225,2225, 0, 0, 40000, 66,0 }, + {2226,2226, 0, 0, 40000, 100,0 }, + {2227,2227, 0, 0, 40000, 73,0 }, + {2228,2228, 0, 0, 40000, 73,0 }, + {2229,2229, 0, 0, 40000, 66,0 }, + {2230,2230, 0, 0, 40000, 66,0 }, + {2231,2231, 0, 0, 40000, 80,0 }, + {2232,2232, 0, 0, 40000, 66,0 }, + {2233,2233, 0, 0, 40000, 80,0 }, + {2234,2234, 0, 0, 40000, 660,0 }, + {2235,2235, 0, 0, 40000, 120,0 }, + {2236,2236, 0, 0, 9820, 393,0 }, + {2237,2237, 0, 0, 40000, 73,0 }, + {2238,2238, 0, 0, 3620, 1166,0 }, + {2239,2239, 0, 0, 40000, 0,0 }, + {2240,2240, 0, 0, 40000, 0,0 }, + {2241,2241, 0, 0, 3020, 66,0 }, + {2242,2242, 0, 0, 6053, 1240,0 }, + {2243,2243, 0, 0, 633, 126,0 }, + {2244,2244, 0, 0, 40000, 66,0 }, + {2245,2245, 0, 0, 40000, 73,0 }, + {2246,2246, 0, 0, 626, 246,0 }, + {2247,2247, 60, 0, 173, 93,0 }, + {2248,2248, 60, 0, 673, 206,0 }, + {2249,2249, 48, 0, 673, 200,0 }, + {2250,2250, 60, 0, 1873, 653,0 }, + {2251,2251, 60, 0, 673, 200,0 }, + {2252,2252, 66, 0, 306, 120,0 }, + {2253,2253, 60, 0, 673, 200,0 }, + {2249,2249, 64, 0, 673, 206,0 }, + {2254,2254, 60, 0, 246, 106,0 }, + {2255,2255, 60, 0, 193, 120,0 }, + {2256,2256, 56, 0, 206, 13,0 }, + {2257,2257, 53, 0, 433, 73,0 }, + {2258,2258, 60, 0, 220, 113,0 }, + {2259,2259, 48, 0, 300, 66,0 }, + {2260,2260, 67, 0, 273, 60,0 }, + {2261,2261, 60, 0, 973, 360,0 }, + {2261,2261, 72, 0, 806, 273,0 }, + {2262,2262, 60, 0, 173, 93,0 }, + {2263,2263, 0, 0, 2493, 866,0 }, + {2264,2264, 24, 0, 173, 93,0 }, + {2265,2265, 36, 0, 140, 0,0 }, + { 343, 343, 36, 0, 146, 80,0 }, + { 347, 347, 0, 0, 353, 133,0 }, + { 347, 347, 12, 0, 420, 146,0 }, + {2266,2266, 12, 0, 346, 100,0 }, + {2267,2267, 24, 0, 106, 46,0 }, + {2267,2267, 36, 0, 100, 0,0 }, + {2268,2268, 0, 0, 1006, 293,0 }, + {2266,2266, 24, 0, 293, 93,0 }, + {2269,2269, 88, 0, 1106, 120,0 }, + {2270,2270, 88, 0, 666, 120,0 }, + {2271,2271, 13, 0, 760, 360,0 }, + { 351, 351, 0, 0, 966, 346,0 }, + {2271,2271, 15, 0, 760, 420,0 }, + {2272,2272, 0, 0, 4513, 640,0 }, + {2273,2273, 0, 0, 15486, 1580,0 }, + {2274,2274, 0, 0, 6940, 66,0 }, + {2275,2275, 0, 0, 6866, 2380,0 }, + {2276,2276, 0, 0, 7613, 1566,0 }, + {2277,2277, 0, 0, 1186, 420,0 }, + {2278,2278, 0, 0, 1166, 400,0 }, + {2279,2279, 0, 0, 40000, 2940,0 }, + {2280,2280, 0, 0, 40000, 0,0 }, + {2281,2281, 0, 0, 18226, 786,0 }, + {2282,2282, 0, 0, 40000, 0,0 }, + {2283,2283, 0, 0, 713, 200,0 }, + {2284,2284, 0, 0, 40000, 126,0 }, + {2285,2285, 0, 0, 40000, 353,0 }, + {2286,2286, 0, 0, 40000, 333,0 }, + {2287,2287, 0, 0, 40000, 0,0 }, + {2288,2288, 0, 0, 40000, 0,0 }, + {2289,2289, 0, 0, 40000, 0,0 }, + {2290,2290, 0, 0, 40000, 0,0 }, + {2291,2291, 0, 0, 40000, 73,0 }, + {2292,2292, 0, 0, 40000, 66,0 }, + {2293,2293, 0, 0, 15893, 153,0 }, + {2294,2294, 0, 0, 40000, 253,0 }, + {2295,2295, 0, 0, 2813, 333,0 }, + {2296,2296, 0, 0, 40000, 3920,0 }, + {2297,2297, 79, 0, 113, 0,0 }, + {2297,2297, 72, 0, 126, 140,0 }, + {2298,2298, 72, 0, 100, 26,0 }, + {2298,2298, 79, 0, 100, 0,0 }, + { 554, 554, 60, 0, 400, 126,0 }, + {2299,2299, 72, 0, 793, 173,0 }, + {2300,2300, 84, 0, 226, 66,0 }, + { 555, 555, 66, 0, 113, 0,0 }, + {2301,2302, 35, 4, 2333, 800,0 }, + {2303,2304, 52, 4, 120, 0,0 }, + {2305,1548, 48, 4, 173, 0,0 }, + {1595,1595, 58, 0, 146, 166,0 }, + {2305,1548, 60, 4, 173, 0,0 }, + {2306,2307, 47, 4, 1893, 700,0 }, + {2306,2307, 43, 4, 1953, 740,0 }, + {2306,2307, 49, 4, 1880, 686,0 }, + {2306,2307, 51, 4, 1886, 706,0 }, + {2306,2307, 54, 4, 1906, 720,0 }, + {2306,2307, 57, 4, 1900, 720,0 }, + {2306,2307, 72, 4, 1593, 606,0 }, + {2306,2307, 60, 4, 1900, 720,0 }, + {2306,2307, 76, 4, 1593, 606,0 }, + {2306,2307, 84, 4, 1593, 613,0 }, + {2306,2307, 36, 4, 2386, 920,0 }, + {1560,2308, 65, 4, 293, 213,0 }, + {2309,2310, 84, 4, 1373, 306,0 }, + {1564,1564, 83, 0, 220, 113,0 }, + { 380, 381, 84, 4, 1593, 566,0 }, + {1568,1568, 24, 0, 1833, 613,0 }, + {2306,2307, 77, 4, 1593, 606,0 }, + {2311,2312, 60, 4, 286, 0,0 }, + {2313,2314, 65, 4, 513, 0,0 }, + {2315,2315, 59, 0, 106, 0,0 }, + {2316,2316, 51, 0, 386, 373,0 }, + {1612,1612, 45, 0, 393, 380,0 }, + {2317,2317, 71, 0, 446, 180,0 }, + {2318,2318, 60, 0, 280, 20,0 }, + {2319,2319, 58, 0, 393, 373,0 }, + {2320,2320, 53, 0, 393, 380,0 }, + { 397, 397, 64, 0, 220, 86,0 }, + {2321,2321, 71, 0, 106, 46,0 }, + {2322,2322, 61, 0, 986, 340,0 }, + {2323,2323, 61, 0, 1893, 633,0 }, + {2324, 392, 44, 4, 166, 46,0 }, + {2324, 393, 40, 4, 460, 60,0 }, + {1595,1595, 69, 0, 126, 140,0 }, + {1595,1595, 68, 0, 126, 140,0 }, + {1595,1595, 63, 0, 146, 166,0 }, + {2325,2326, 74, 4, 380, 106,0 }, + {2327,2328, 60, 4, 1026, 333,0 }, + {2329,2330, 80, 4, 40000, 0,0 }, + {2331,2332, 64, 4, 1900, 640,0 }, + { 397, 397, 72, 0, 193, 80,0 }, + {2333,2334, 78, 4, 820, 0,0 }, + {1608,1609, 82, 4, 1580, 0,0 }, + {2315,2315, 48, 0, 106, 0,0 }, + {2316,2316, 53, 0, 386, 373,0 }, + {2335,2335, 0, 0, 3586, 1133,0 }, + {2336,2337, 0, 4, 1186, 420,0 }, + {2338,2339, 0, 4, 40000, 320,0 }, + {2340,2340, 0, 0, 8826, 1346,0 }, + {2341,2341, 0, 0, 3440, 753,0 }, + {2342,2342, 0, 0, 40000, 360,0 }, + {2343,2343, 0, 0, 40000, 413,0 }, + {2344,2345, 0, 4, 40000, 60,0 }, + {2346,2346, 0, 0, 40000, 60,0 }, + {2347,2348, 0, 4, 40000, 126,0 }, + {2349,2350, 0, 4, 40000, 73,0 }, + {2351,2352, 0, 4, 40000, 73,0 }, + {2353,2354, 0, 4, 40000, 86,0 }, + {2355,2356, 0, 4, 40000, 453,0 }, + {2357,2357, 14, 0, 186, 20,0 }, + {2358,2358, 35, 0, 246, 73,0 }, + {2357,2357, 19, 0, 166, 26,0 }, + {2359,2359, 43, 0, 286, 133,0 }, + {2360,2360, 41, 0, 300, 113,0 }, + {2360,2360, 43, 0, 253, 106,0 }, + {2360,2360, 45, 0, 240, 100,0 }, + {2360,2360, 47, 0, 240, 100,0 }, + {2361,2362, 0, 4, 14720, 333,0 }, + {2363,2363, 0, 0, 7373, 1246,0 }, + {2364,2364, 0, 0, 4900, 233,0 }, + {2365,2365, 0, 0, 5106, 606,0 }, + {2366,2366, 0, 0, 1333, 153,0 }, + {2367,2367, 0, 0, 2093, 840,0 }, + {2368,2368, 0, 0, 3700, 226,0 }, + {2369,2369, 0, 0, 3546, 0,0 }, + {2370,2370, 0, 0, 4606, 420,0 }, + {2371,2371, 0, 0, 14366, 606,0 }, + {2372,2372, 0, 0, 40000, 426,0 }, + {2373,2373, 0, 0, 3700, 200,0 }, + {2374,2374, 0, 0, 880, 440,0 }, + {2375,2375, 0, 0, 4660, 660,0 }, + {2376,2376, 0, 0, 3600, 1153,0 }, + {2377,2377, 0, 0, 40000, 73,0 }, + {2378,2378, 0, 0, 40000, 53,0 }, + {2379,2379, 0, 0, 40000, 333,0 }, + {2380,2380, 0, 0, 40000, 73,0 }, + {2381,2381, 0, 0, 40000, 73,0 }, + {2382,2382, 0, 0, 40000, 66,0 }, + {2383,2383, 0, 0, 40000, 73,0 }, + {2384,2384, 0, 0, 40000, 73,0 }, + {2385,2385, 0, 0, 840, 226,0 }, + {2386,2386, 0, 0, 2093, 86,0 }, + {2387,2387, 0, 0, 906, 73,0 }, + { 402, 402, 0, 0, 273, 60,0 }, + {2388,2388, 0, 0, 40000, 820,0 }, + {2389,2389, 0, 0, 4740, 93,0 }, + {2390,2390, 0, 0, 706, 106,0 }, + {2391,2391, 0, 0, 40000, 0,0 }, + {2392,2392, 0, 0, 3840, 2306,0 }, + {2393,2393, 0, 0, 3400, 493,0 }, + {2394,2394, 0, 0, 40000, 53,0 }, + {2395,2395, 0, 0, 40000, 133,0 }, + {2396,2397, 0, 4, 3093, 1400,0 }, + {2398,2398, 0, 0, 1080, 580,0 }, + {2399,2400, 0, 4, 2220, 400,0 }, + {2401,2401, 0, 0, 40000, 193,0 }, + {2402,2402, 0, 0, 40000, 60,0 }, + {2403,2404, 0, 4, 40000, 146,0 }, + {2405,2406, 0, 4, 40000, 133,0 }, + {2407,2408, 0, 4, 40000, 66,0 }, + {2409,2409, 0, 0, 40000, 0,0 }, + {2410,2410, 0, 0, 40000, 73,0 }, + {2411,2411, 0, 0, 40000, 66,0 }, + {2412,2413, 0, 4, 40000, 153,0 }, + {2414,2414, 0, 0, 40000, 126,0 }, + {2415,2416, 0, 4, 40000, 466,0 }, + {2417,2418, 0, 4, 40000, 113,0 }, + {2419,2420, 0, 4, 1280, 73,0 }, + {2421,2422, 0, 4, 1113, 146,0 }, + {2423,2424, 0, 4, 3660, 113,0 }, + {2425,2426, 0, 4, 40000, 80,0 }, + {2427,2427, 33, 0, 300, 246,0 }, + {2428,2429, 38, 4, 53, 0,0 }, + {2430,2430, 38, 0, 106, 0,0 }, + {2431,2431, 38, 0, 340, 20,0 }, + {2432,2432, 40, 0, 73, 0,0 }, + {2433,2434, 41, 4, 300, 0,0 }, + {2435,2435, 0, 0, 133, 73,0 }, + {2435,2435, 41, 0, 133, 73,0 }, + {2360,2360, 48, 0, 240, 100,0 }, + {2436,2436, 17, 0, 4620, 1553,0 }, + {2360,2360, 50, 0, 240, 100,0 }, + {2435,2435, 45, 0, 126, 66,0 }, + {2437,2437,254, 2, 6, 0,0 }, + {2438,2438, 60, 0, 226, 93,0 }, + {2439,2439, 56, 0, 233, 93,0 }, + {2440,2440, 60, 0, 140, 66,0 }, + {2440,2440, 55, 0, 140, 60,0 }, + {2441,2441, 63, 0, 286, 126,0 }, + {2442,2442, 57, 0, 173, 93,0 }, + {2443,2443, 0, 0, 40000, 280,0 }, + {2444,2444, 0, 0, 40000, 0,0 }, + {2445,2445, 0, 0, 40000, 746,0 }, + {2446,2446, 0, 0, 40000, 353,0 }, + {2447,2447, 0, 0, 40000, 1173,0 }, + {2448,2448, 0, 0, 40000, 146,0 }, + {2449,2449, 0, 0, 40000, 1160,0 }, + {2450,2450, 0, 0, 40000, 353,0 }, + {2451,2451, 0, 0, 18313, 6046,0 }, + {2452,2452, 0, 0, 1206, 420,0 }, + { 752, 752, 55, 0, 173, 20,0 }, + {2453,2453, 0, 0, 2860, 806,0 }, + {2454,2454, 0, 0, 2506, 126,0 }, + {2455,2455, 0, 0, 520, 93,0 }, + {2456,2456, 0, 0, 1420, 160,0 }, + {2457,2457, 0, 0, 40000, 53,0 }, + {2458,2458, 0, 0, 9106, 100,0 }, + {2459,2459, 0, 0, 3706, 100,0 }, + {2460,2460, 0, 0, 17933, 100,0 }, + {2461,2461, 0, 0, 40000, 0,0 }, + {2462,2462, 0, 0, 40000, 66,0 }, + {2463,2463, 0, 0, 40000, 0,0 }, + { 884, 884, 0, 0, 306, 73,0 }, + { 884, 884, 28, 0, 306, 73,0 }, + {2464,2464, 29, 0, 226, 93,0 }, + { 886, 886, 31, 0, 113, 0,0 }, + { 360, 360, 32, 0, 133, 40,0 }, + { 361, 361, 33, 0, 286, 80,0 }, + {2453,2453, 34, 0, 2873, 813,0 }, + { 888, 888, 29, 0, 246, 46,0 }, + { 886, 886, 55, 0, 100, 0,0 }, + { 890, 890, 48, 0, 240, 60,0 }, + { 884, 884, 58, 0, 146, 26,0 }, + {2465,2465, 45, 0, 173, 93,0 }, + {2465,2465, 43, 0, 173, 93,0 }, + {2466,2466, 73, 0, 1633, 86,0 }, + {2467,2467, 72, 0, 866, 553,0 }, + {2468,2468, 76, 0, 1380, 0,0 }, + {2467,2467, 84, 0, 873, 560,0 }, + {2468,2468, 36, 0, 1933, 880,0 }, + {2469,2469, 65, 0, 300, 120,0 }, + {2470,2470, 83, 0, 193, 86,0 }, + {2471,2471, 50, 0, 966, 126,0 }, + {2468,2468, 77, 0, 1373, 620,0 }, + { 897, 897, 55, 0, 126, 40,0 }, + {2472,2472, 60, 0, 180, 140,0 }, + { 897, 897, 50, 0, 126, 40,0 }, + {2473,2473, 42, 0, 633, 240,0 }, + {2473,2473, 46, 0, 513, 200,0 }, + {2474,2474, 71, 0, 433, 180,0 }, + {2474,2474, 60, 0, 513, 206,0 }, + {2455,2455, 58, 0, 220, 46,0 }, + {2455,2455, 53, 0, 286, 60,0 }, + {2475,2475, 91, 0, 186, 100,0 }, + {2476,2476, 61, 0, 226, 26,0 }, + {2477,2477, 61, 0, 886, 73,0 }, + {2478,2478, 44, 0, 120, 73,0 }, + {2479,2479, 40, 0, 933, 73,0 }, + {2480,2480, 69, 0, 146, 33,0 }, + { 361, 361, 68, 0, 153, 26,0 }, + { 361, 361, 63, 0, 180, 26,0 }, + {2481,2481, 74, 0, 153, 73,0 }, + {2482,2482, 60, 0, 280, 100,0 }, + { 908, 908, 80, 0, 160, 26,0 }, + {2483,2483, 64, 0, 986, 353,0 }, + {2483,2483, 73, 0, 813, 306,0 }, + {2483,2483, 70, 0, 820, 306,0 }, + { 886, 886, 68, 0, 93, 0,0 }, + { 886, 886, 48, 0, 106, 0,0 }, + {2484,2484, 0, 0, 40000, 0,0 }, + {2485,2485, 0, 0, 3226, 753,0 }, + {2486,2486, 0, 0, 1773, 553,0 }, + {2487,2487, 0, 0, 7473, 2460,0 }, + {2488,2488, 0, 0, 40000, 0,0 }, + {2489,2489, 0, 0, 40000, 353,0 }, + {2490,2490, 0, 0, 40000, 206,0 }, + {2491,2491, 0, 0, 40000, 86,0 }, + {2492,2492, 0, 0, 4740, 86,0 }, + {2493,2493, 0, 0, 6193, 193,0 }, + {2494,2494, 0, 0, 6200, 240,0 }, + {2495,2495, 0, 0, 40000, 0,0 }, + {2496,2496, 0, 0, 1586, 73,0 }, + {2497,2497, 0, 0, 560, 73,0 }, + {2498,2498, 0, 0, 40000, 480,0 }, + {2499,2499, 0, 0, 40000, 80,0 }, + {2500,2500, 0, 0, 40000, 66,0 }, + {2501,2501, 0, 0, 40000, 380,0 }, + {2502,2502, 0, 0, 280, 100,0 }, + {2503,2503, 0, 0, 6193, 233,0 }, + {2504,2504, 0, 0, 40000, 380,0 }, + {2505,2505, 0, 0, 40000, 0,0 }, + {2506,2506, 0, 0, 40000, 380,0 }, + {2507,2507, 0, 0, 40000, 200,0 }, + {2508,2508, 0, 0, 40000, 320,0 }, + {2509,2509, 0, 0, 40000, 126,0 }, + {2510,2510, 0, 0, 40000, 293,0 }, + {2511,2511, 0, 0, 40000, 0,0 }, + {2512,2512, 0, 0, 40000, 40,0 }, + {2513,2513, 0, 0, 40000, 106,0 }, + {2514,2514, 0, 0, 3846, 73,0 }, + {2515,2515, 0, 0, 40000, 0,0 }, + {2516,2516, 0, 0, 40000, 73,0 }, + {2517,2517, 0, 0, 40000, 533,0 }, + {2518,2518, 0, 0, 40000, 1020,0 }, + {2519,2519, 0, 0, 40000, 73,0 }, + {2520,2520, 0, 0, 40000, 53,0 }, + {2521,2521, 0, 0, 6153, 1433,0 }, + {2522,2522, 0, 0, 18813, 773,0 }, + {2523,2523, 0, 0, 40000, 433,0 }, + {2524,2524, 0, 0, 40000, 0,0 }, + {2525,2525, 0, 0, 40000, 133,0 }, + {2526,2526, 0, 0, 4486, 73,0 }, + { 346, 346, 30, 0, 540, 33,0 }, + { 346, 346, 31, 0, 406, 20,0 }, + { 346, 346, 32, 0, 406, 20,0 }, + { 346, 346, 33, 0, 406, 73,0 }, + { 346, 346, 34, 0, 406, 20,0 }, + { 346, 346, 35, 0, 406, 20,0 }, + { 346, 346, 37, 0, 406, 73,0 }, + { 346, 346, 39, 0, 406, 73,0 }, + { 346, 346, 41, 0, 406, 20,0 }, + { 346, 346, 43, 0, 306, 20,0 }, + { 346, 346, 45, 0, 306, 20,0 }, + { 346, 346, 47, 0, 306, 20,0 }, + { 346, 346, 48, 0, 306, 20,0 }, + { 346, 346, 49, 0, 306, 20,0 }, + { 512, 512, 84, 0, 353, 466,0 }, + {2206,2206, 84, 0, 440, 180,0 }, + {2527,2527, 55, 0, 100, 0,0 }, + {2528,2528, 36, 0, 400, 160,0 }, + {2529,2529, 38, 0, 313, 226,0 }, + {2530,2530, 60, 0, 286, 133,0 }, + {2531,2531, 38, 0, 200, 100,0 }, + {2532,2532, 17, 0, 6186, 240,0 }, + {2532,2532, 18, 0, 6186, 240,0 }, + {2532,2532, 19, 0, 6193, 233,0 }, + {2532,2532, 20, 0, 6193, 193,0 }, + {2532,2532, 21, 0, 6193, 193,0 }, + {2532,2532, 22, 0, 6193, 193,0 }, + {2532,2532, 23, 0, 6193, 193,0 }, + {2532,2532, 24, 0, 6193, 193,0 }, + {2532,2532, 25, 0, 6193, 193,0 }, + {2532,2532, 26, 0, 6193, 193,0 }, + {2532,2532, 27, 0, 6193, 253,0 }, + {2532,2532, 28, 0, 6193, 246,0 }, + {2532,2532, 29, 0, 6193, 246,0 }, + {2533,2533, 84, 0, 433, 180,0 }, + {2534,2534, 48, 0, 280, 93,0 }, + {2535,2535, 65, 0, 1166, 360,0 }, + {2536,2536, 65, 0, 1853, 633,0 }, + {2537,2537, 55, 0, 453, 366,0 }, + {2537,2537, 41, 0, 540, 433,0 }, + { 346, 346, 63, 0, 240, 66,0 }, + { 346, 346, 55, 0, 240, 66,0 }, + {2538,2538, 55, 0, 2586, 200,0 }, + {2538,2538, 53, 0, 2586, 200,0 }, + {2534,2534, 50, 0, 280, 93,0 }, + { 506, 506, 84, 0, 693, 566,0 }, + { 506, 506, 74, 0, 693, 560,0 }, + { 504, 504, 84, 0, 1566, 546,0 }, + { 504, 504, 74, 0, 1586, 560,0 }, + {2539,2539, 84, 0, 440, 20,0 }, + {2540,2540, 74, 0, 126, 26,0 }, + {1911,1911, 48, 0, 500, 180,0 }, + {1911,1911, 36, 0, 606, 220,0 }, + {2541,2541, 74, 0, 686, 560,0 }, + {2542,2542, 0, 0, 7313, 13,0 }, + {2543,2543, 0, 0, 40000, 1306,0 }, + {2544,2544, 0, 0, 40000, 0,0 }, + {2545,2545, 0, 0, 4613, 13,0 }, + {2546,2547, 0, 4, 6933, 133,0 }, + {2548,2549, 0, 4, 40000, 86,0 }, + {2550,2550, 0, 0, 9233, 100,0 }, + {2551,2552, 0, 4, 4640, 73,0 }, + {2553,2553, 0, 0, 40000, 73,0 }, + {2554,2554, 0, 0, 40000, 0,0 }, + {2555,2556, 0, 4, 40000, 73,0 }, + {2557,2557, 0, 0, 40000, 60,0 }, + {2558,1467, 0, 4, 40000, 66,0 }, + {2559,2560, 0, 4, 40000, 40,0 }, + {2561,2561, 0, 0, 40000, 186,0 }, + {2562,2562, 0, 0, 4026, 66,0 }, + {2563,2564, 0, 4, 14586, 80,0 }, + {2565,2565, 0, 0, 40000, 0,0 }, + {2566,2567, 0, 4, 40000, 40,0 }, + {2568,2568, 0, 0, 4020, 73,0 }, + {2569,2569, 0, 0, 40000, 0,0 }, + {2570,2570, 0, 0, 40000, 0,0 }, + {2571,2572, 0, 4, 40000, 126,0 }, + {2573,2574, 0, 4, 40000, 100,0 }, + {2575,2575, 0, 0, 40000, 213,0 }, + { 229,2576, 0, 4, 40000, 166,0 }, + {2577,2577, 0, 0, 7366, 53,0 }, + { 239,2578, 0, 4, 40000, 133,0 }, + {2579,2579, 0, 0, 40000, 80,0 }, + {2580,2580, 0, 0, 40000, 140,0 }, + {2581,2582, 0, 4, 16980, 1173,0 }, + {2583,2584, 0, 4, 726, 100,0 }, + {2585,2586, 0, 4, 40000, 73,0 }, + {2587,2588, 0, 4, 40000, 73,0 }, + {2589,2589, 0, 0, 40000, 60,0 }, + {2590,2590, 0, 0, 40000, 80,0 }, + {2591,2592, 0, 4, 40000, 73,0 }, + {2593,2594, 0, 4, 40000, 60,0 }, + {2595,2595, 0, 0, 40000, 66,0 }, + {2596,2597, 0, 4, 40000, 66,0 }, + {2598,2599, 0, 4, 40000, 60,0 }, + {2600,2601, 0, 4, 40000, 173,0 }, + {2602,2602, 0, 0, 40000, 60,0 }, + {2603,2603, 0, 0, 40000, 73,0 }, + {2604,2604, 0, 0, 40000, 93,0 }, + {2605,2606, 0, 4, 40000, 73,0 }, + {2607,2607, 0, 0, 40000, 66,0 }, + {2608,2609, 0, 4, 40000, 66,0 }, + {2610,2610, 0, 0, 40000, 86,0 }, + {2611,2611, 0, 0, 40000, 60,0 }, + {2612,2612, 0, 0, 14286, 73,0 }, + {2613,2613, 0, 0, 40000, 0,0 }, + {2614,2615, 0, 4, 40000, 73,0 }, + {2616,2617, 0, 4, 40000, 66,0 }, + {2618,2619, 0, 4, 133, 0,0 }, + {2620,2621, 0, 4, 40000, 1280,0 }, + {2622,2623, 0, 4, 40000, 160,0 }, + {2624,2625, 0, 4, 40000, 0,0 }, + {2626,2627, 0, 4, 40000, 73,0 }, + {2628,2629, 0, 4, 40000, 0,0 }, + {1516,2630, 0, 4, 1193, 406,0 }, + {2631,2632, 0, 4, 40000, 553,0 }, + {2633,2633, 0, 0, 40000, 40,0 }, + {2634,2635, 0, 4, 40000, 773,0 }, + {2636,2636, 0, 0, 40000, 320,0 }, + {2637,2637, 0, 0, 1880, 73,0 }, + {2638,2639, 0, 4, 486, 0,0 }, + {2640,2641, 0, 4, 17020, 1193,0 }, + {2642,2642, 0, 0, 40000, 720,0 }, + {2643,2644, 0, 4, 1880, 40,0 }, + {2645,2645, 0, 0, 40000, 73,0 }, + {2646,2647, 0, 4, 40000, 46,0 }, + {2648,2648, 0, 0, 2466, 80,0 }, + {2649,2649, 0, 0, 40000, 193,0 }, + {2650,2651, 0, 4, 993, 73,0 }, + {2652,2652, 0, 0, 40000, 220,0 }, + {2653,2654, 0, 4, 40000, 46,0 }, + {2655,2656, 0, 4, 40000, 46,0 }, + {2657,2657, 0, 0, 40000, 66,0 }, + {2658,2658, 35, 0, 626, 20,0 }, + {2659,2659, 35, 0, 306, 26,0 }, + {2660,2660, 52, 0, 126, 26,0 }, + {2661,2661, 60, 0, 286, 20,0 }, + {2662,2662, 58, 0, 113, 0,0 }, + {2663,2663, 60, 0, 380, 20,0 }, + {2664,2664, 50, 0, 1640, 66,0 }, + {2665,2665, 43, 0, 153, 20,0 }, + {2664,2664, 55, 0, 1640, 20,0 }, + {1553,1553, 43, 0, 160, 80,0 }, + {2666,2666, 50, 0, 980, 20,0 }, + {2667,2667, 43, 0, 446, 73,0 }, + {2666,2666, 53, 0, 1000, 80,0 }, + {2666,2666, 57, 0, 700, 73,0 }, + {2668,2668, 72, 0, 773, 13,0 }, + {2666,2666, 60, 0, 686, 20,0 }, + { 373, 373, 76, 0, 826, 20,0 }, + {2669,2669, 84, 0, 713, 20,0 }, + {2670,2670, 42, 0, 1186, 20,0 }, + {2671,2671, 65, 0, 293, 33,0 }, + {2672,2672, 84, 0, 386, 33,0 }, + {2673,2673, 84, 0, 1366, 20,0 }, + {2674,2674, 24, 0, 960, 73,0 }, + { 383, 383, 77, 0, 800, 20,0 }, + {2675,2675, 58, 0, 426, 26,0 }, + {2676,2676, 53, 0, 426, 20,0 }, + {2677,2677, 64, 0, 200, 66,0 }, + {2678,2678, 71, 0, 113, 13,0 }, + {2679,2679, 44, 0, 766, 66,0 }, + {2680,2680, 40, 0, 460, 60,0 }, + {2681,2681, 69, 0, 126, 26,0 }, + {2682,2682, 60, 0, 573, 66,0 }, + {2683,2683, 80, 0, 226, 20,0 }, + {2684,2684, 64, 0, 2693, 20,0 }, + {2685,2685, 72, 0, 120, 66,0 }, + {2686,2686, 70, 0, 820, 20,0 }, + {2687,2687, 48, 0, 173, 20,0 }, + {2688,2688, 53, 0, 980, 33,0 }, + {2689,2690, 0, 4, 40000, 286,0 }, + {2691,2692, 0, 4, 2340, 100,0 }, + {2693,2694, 0, 4, 380, 80,0 }, + {2695,2696, 0, 4, 14793, 73,0 }, + {2697,2698, 0, 4, 40000, 40,0 }, + { 192,2699, 0, 4, 40000, 73,0 }, + {2700,2701, 0, 4, 973, 126,0 }, + {2702,2703, 0, 4, 4666, 106,0 }, + {2704,2705, 0, 4, 40000, 73,0 }, + {2706,2707, 0, 4, 40000, 73,0 }, + {2708,2709, 0, 4, 40000, 73,0 }, + {2710,2711, 0, 4, 2053, 0,0 }, + {2712,1473, 0, 4, 320, 26,0 }, + {2713,2714, 0, 4, 573, 93,0 }, + {2715,2716, 0, 4, 6513, 0,0 }, + {1478,2717, 0, 4, 40000, 146,0 }, + {2718,2719, 0, 4, 40000, 66,0 }, + { 286,2720, 0, 4, 40000, 73,0 }, + {2721,2722, 0, 4, 40000, 86,0 }, + {2723,2724, 0, 4, 40000, 60,0 }, + {2725,2726, 0, 4, 393, 73,0 }, + {2727,2724, 0, 4, 40000, 60,0 }, + {1514,2728, 0, 4, 40000, 180,0 }, + {2729,2730, 0, 4, 40000, 0,0 }, + {2731,2732, 0, 4, 486, 0,0 }, + {2733,2734, 0, 4, 733, 0,0 }, + {2735,2736, 0, 4, 286, 40,0 }, + {2737,2738, 0, 4, 40000, 73,0 }, + {2739,2740, 0, 4, 1326, 746,0 }, + {2741,2742, 0, 4, 1340, 700,0 }, + {2743,2744, 0, 4, 40000, 0,0 }, + {2745,2746, 0, 4, 2046, 0,0 }, + {2747,2747, 35, 0, 386, 166,0 }, + {2748,2748, 60, 0, 493, 193,0 }, + {2749,2749, 43, 0, 126, 66,0 }, + {2750,2750, 0, 0, 3740, 1260,0 }, + {2751,2752, 0, 4, 14846, 353,0 }, + {2753,2754, 0, 4, 10266, 0,0 }, + {2755,2756, 0, 4, 18286, 146,0 }, + {2757,2758, 0, 4, 14520, 333,0 }, + {2759,2760, 0, 4, 14686, 633,0 }, + {2761,2762, 0, 4, 14826, 300,0 }, + {2763,2764, 0, 4, 10493, 0,0 }, + {2765,2766, 0, 4, 40000, 60,0 }, + {2767,2768, 0, 4, 40000, 80,0 }, + {2769,2770, 0, 4, 40000, 80,0 }, + {2771,2772, 0, 4, 40000, 73,0 }, + {2773,2774, 0, 4, 40000, 73,0 }, + {2775,2776, 0, 4, 40000, 80,0 }, + {2777,2778, 0, 4, 40000, 73,0 }, + {2779,2780, 0, 4, 40000, 73,0 }, + {2781,2782, 0, 4, 40000, 66,0 }, + {2783,2784, 0, 4, 7260, 186,0 }, + {2785,2786, 0, 4, 10386, 0,0 }, + {2787,2788, 0, 4, 40000, 246,0 }, + {2789,2790, 0, 4, 9173, 746,0 }, + {2791,2792, 0, 4, 7440, 666,0 }, + {2793,2794, 0, 4, 40000, 0,0 }, + {2795,2796, 0, 4, 40000, 413,0 }, + {2795,2797, 0, 4, 40000, 1506,0 }, + {2798,2799, 0, 4, 40000, 60,0 }, + {2800,2801, 0, 4, 40000, 233,0 }, + {2802,2803, 0, 4, 40000, 80,0 }, + {2804,2805, 0, 4, 40000, 80,0 }, + {2806,2807, 0, 4, 4520, 80,0 }, + {2808,2809, 0, 4, 40000, 73,0 }, + {2810,2811, 0, 4, 1186, 100,0 }, + {2812,2813, 0, 4, 953, 153,0 }, + {2814,2815, 0, 4, 14786, 126,0 }, + {2816,2817, 0, 4, 14800, 193,0 }, + {2818,2819, 0, 4, 14573, 626,0 }, + {2820,2821, 0, 4, 2200, 73,0 }, + {2822,2823, 0, 4, 373, 86,0 }, + {2824,2825, 0, 4, 12780, 200,0 }, + {2826,2827, 0, 4, 40000, 73,0 }, + {2828,2829, 0, 4, 9193, 146,0 }, + {2830,2831, 0, 4, 2540, 326,0 }, + {2832,2833, 0, 4, 6933, 200,0 }, + {2834,2835, 0, 4, 40000, 413,0 }, + {2836,2837, 0, 4, 4826, 1313,0 }, + {2838,2839, 0, 4, 14740, 340,0 }, + {2840,2841, 0, 4, 1886, 653,0 }, + {2842,2843, 0, 4, 5280, 260,0 }, + {2844,2845, 0, 4, 40000, 240,0 }, + {2846,2847, 0, 4, 40000, 240,0 }, + {2848,2849, 0, 4, 40000, 240,0 }, + {2850,2851, 0, 4, 40000, 406,0 }, + {2852,2853, 0, 4, 40000, 406,0 }, + {2854,2855, 0, 4, 40000, 146,0 }, + {2856,2856, 0, 0, 2400, 1126,0 }, + {2857,2857, 0, 0, 2400, 1126,0 }, + {2858,2859, 0, 4, 4613, 73,0 }, + {2860,2861, 0, 4, 40000, 426,0 }, + {2862,2863, 0, 4, 4580, 100,0 }, + {2864,2865, 0, 4, 40000, 80,0 }, + {2866,2867, 0, 4, 5300, 53,0 }, + {2868,2869, 0, 4, 5313, 113,0 }, + {2870,2871, 0, 4, 7080, 186,0 }, + {2872,2873, 0, 4, 4720, 106,0 }, + {2874,2875, 0, 4, 40000, 73,0 }, + {2876,2877, 0, 4, 1640, 0,0 }, + {2878,2879, 0, 4, 7306, 186,0 }, + {2880,2881, 0, 4, 7373, 1246,0 }, + {2882,2883, 0, 4, 4620, 93,0 }, + {2884,2885, 0, 4, 3460, 926,0 }, + {2886,2887, 0, 4, 40000, 73,0 }, + {2888,2888, 0, 0, 18926, 426,0 }, + {2889,2889, 0, 0, 18520, 73,0 }, + {2890,2890, 0, 0, 18473, 73,0 }, + {2891,2892, 0, 4, 40000, 93,0 }, + {2893,2893, 0, 0, 8006, 133,0 }, + {2894,2894, 0, 0, 18533, 66,0 }, + {2895,2895, 0, 0, 14786, 4966,0 }, + {2896,2897, 0, 4, 40000, 80,0 }, + {2898,2899, 0, 4, 40000, 73,0 }, + {2353,2900, 0, 4, 18520, 86,0 }, + {2901,2901, 0, 0, 40000, 0,0 }, + {2902,2903, 0, 4, 40000, 100,0 }, + {2904,2905, 0, 4, 40000, 93,0 }, + {2906,2907, 0, 4, 40000, 73,0 }, + {2908,2909, 0, 4, 10720, 153,0 }, + {2910,2911, 0, 4, 40000, 73,0 }, + {2912,2912, 0, 0, 40000, 40,0 }, + {2913,2914, 0, 4, 8720, 446,0 }, + {2915,2916, 0, 4, 14706, 653,0 }, + {2917,2918, 0, 4, 9213, 426,0 }, + {2919,2920, 0, 4, 9286, 240,0 }, + {2921,2922, 0, 4, 8706, 413,0 }, + {2923,2924, 0, 4, 2233, 346,0 }, + {2925,2926, 0, 4, 2373, 426,0 }, + {2927,2928, 0, 4, 2353, 233,0 }, + {2929,2929, 0, 0, 40000, 140,0 }, + {2930,2931, 0, 4, 40000, 100,0 }, + {2932,2933, 0, 4, 40000, 73,0 }, + {2934,2935, 0, 4, 40000, 80,0 }, + {2936,2937, 0, 4, 40000, 80,0 }, + {2938,2939, 0, 4, 40000, 246,0 }, + {2940,2940, 0, 0, 553, 446,0 }, + {2941,2941, 0, 0, 40000, 193,0 }, + {2942,2943, 0, 4, 1206, 406,0 }, + {2944,2944, 0, 0, 7026, 1553,0 }, + {2945,2945, 0, 0, 3426, 360,0 }, + {2946,2947, 0, 4, 7313, 646,0 }, + {2948,2948, 0, 0, 40000, 386,0 }, + {2949,2949, 0, 0, 1953, 726,0 }, + {2950,2951, 0, 4, 14606, 106,0 }, + {2952,2953, 0, 4, 40000, 1566,0 }, + {2954,2954, 60, 2, 6, 0,0 }, + {2955,2956, 0, 4, 40000, 240,0 }, + {2957,2958, 0, 4, 40000, 80,0 }, + {2959,2960, 0, 4, 40000, 113,0 }, + {2961,2962, 0, 4, 40000, 240,0 }, + {2963,2963, 0, 0, 8506, 680,0 }, + {2964,2964, 0, 0, 40000, 1593,0 }, + {2436,2436, 49, 0, 1873, 633,0 }, + {2357,2357, 61, 0, 113, 20,0 }, + {2357,2357, 56, 0, 113, 26,0 }, + {2357,2357, 58, 0, 113, 26,0 }, + {2357,2357, 49, 0, 126, 26,0 }, + {2357,2357, 44, 0, 126, 26,0 }, + {2965,2965, 0, 0, 40000, 380,0 }, + {2966,2966, 0, 0, 4440, 66,0 }, + {2967,2967, 0, 0, 8133, 1433,0 }, + {2968,2968, 0, 0, 40000, 126,0 }, + {2969,2969, 0, 0, 40000, 0,0 }, + {2970,2970, 84, 0, 160, 26,0 }, + {2971,2971, 72, 0, 440, 180,0 }, + {2972,2972, 0, 0, 8313, 580,0 }, + {2973,2973, 0, 0, 40000, 160,0 }, + {2974,2974, 0, 0, 40000, 3000,0 }, + {2975,2975, 0, 0, 8300, 493,0 }, + {2976,2976, 0, 0, 973, 673,0 }, + {2977,2977, 0, 0, 40000, 73,0 }, + {2978,2978, 0, 0, 40000, 133,0 }, + {2979,2979, 0, 0, 40000, 140,0 }, + {2980,2980, 0, 0, 40000, 346,0 }, + {2981,2981, 0, 0, 40000, 1006,0 }, + {2982,2982, 0, 0, 40000, 966,0 }, + {2983,2983, 0, 0, 40000, 0,0 }, + {2984,2984, 0, 0, 40000, 0,0 }, + {2985,2985, 0, 0, 40000, 66,0 }, + {2986,2986, 0, 0, 40000, 66,0 }, + {2987,2987, 0, 0, 40000, 46,0 }, + {2988,2988, 0, 0, 40000, 533,0 }, + {2989,2989, 0, 0, 2400, 780,0 }, + {2990,2990, 0, 0, 820, 66,0 }, + {2991,2991, 0, 0, 40000, 240,0 }, + {2992,2992, 0, 0, 40000, 220,0 }, + {2993,2993, 0, 0, 40000, 0,0 }, + {2994,2994, 0, 0, 15100, 73,0 }, + {2995,2995, 0, 0, 40000, 200,0 }, + {2996,2996, 0, 0, 2426, 93,0 }, + {2997,2997, 0, 0, 4640, 1553,0 }, + {2998,2998, 0, 0, 40000, 73,0 }, + {2999,2999, 0, 0, 40000, 73,0 }, + {3000,3000, 0, 0, 1133, 633,0 }, + {3001,3001, 0, 0, 40000, 0,0 }, + {3002,3002, 0, 0, 40000, 1006,0 }, + {3003,3003, 0, 0, 4653, 653,0 }, + {3004,3004, 0, 0, 40000, 1000,0 }, + {3005,3005, 0, 0, 40000, 53,0 }, + {3006,3006, 0, 0, 40000, 60,0 }, + {3007,3007, 0, 0, 40000, 0,0 }, + { 350, 350, 0, 0, 513, 200,0 }, + {3008,3008, 0, 0, 213, 106,0 }, + {3009,3009, 0, 0, 280, 126,0 }, + {3010,3010, 0, 0, 1193, 426,0 }, + {3011,3011, 0, 0, 14653, 4906,0 }, + {3012,3012, 0, 0, 1040, 326,0 }, + {3013,3013, 0, 0, 5740, 2326,0 }, + {3014,3014, 0, 0, 40000, 73,0 }, + {3015,3015, 0, 0, 40000, 240,0 }, + { 350, 350, 36, 0, 380, 153,0 }, + { 369, 369, 37, 0, 213, 66,0 }, + {3008,3008, 38, 0, 213, 106,0 }, + { 369, 369, 24, 0, 193, 13,0 }, + {3008,3008, 32, 0, 206, 106,0 }, + { 369, 369, 48, 0, 186, 20,0 }, + {3009,3009, 42, 0, 220, 106,0 }, + { 369, 369, 50, 0, 186, 73,0 }, + { 369, 369, 52, 0, 186, 73,0 }, + { 369, 369, 54, 0, 186, 33,0 }, + { 369, 369, 55, 0, 186, 33,0 }, + { 369, 369, 57, 0, 180, 33,0 }, + {3010,3010, 51, 0, 966, 353,0 }, + { 144, 144, 61, 0, 213, 126,0 }, + {3016,3016, 0, 0, 8340, 520,0 }, + {3016,3016, 63, 0, 6106, 373,0 }, + {3016,3016, 64, 0, 6073, 380,0 }, + {3017,3017, 40, 0, 206, 100,0 }, + {3017,3017, 70, 0, 160, 93,0 }, + {3018,3018, 0, 0, 40000, 73,0 }, + {3019,3019, 0, 0, 40000, 73,0 }, + {3020,3020, 0, 0, 40000, 73,0 }, + {3021,3021, 0, 0, 40000, 73,0 }, + {3022,3022, 38, 0, 246, 33,0 }, + {2441,2441, 57, 0, 286, 126,0 }, + {3023,3023, 63, 0, 146, 126,0 }, + {3024,3024, 74, 0, 280, 73,0 }, + {3025,3025, 74, 0, 453, 100,0 }, + {3026,3026, 60, 0, 666, 33,0 }, + {1439,1440, 0, 0, 13566, 273,0 }, + {1593,1594, 35, 0, 2200, 673,0 }, + {1564,1565, 35, 0, 740, 280,0 }, + {1443,1444, 0, 0, 11886, 333,0 }, + {1481,1482, 0, 0, 40000, 133,0 }, + { 185, 186, 0, 0, 5980, 1540,0 }, + { 235, 237, 0, 0, 3366, 1093,0 }, + { 239, 240, 0, 0, 40000, 133,0 }, + {1477,1476, 0, 0, 40000, 160,0 }, + { 268, 269, 0, 0, 40000, 80,0 }, + { 176, 177, 0, 0, 40000, 0,0 }, + {1490,1491, 0, 0, 40000, 60,0 }, + { 231, 232, 0, 0, 40000, 146,0 }, + { 233, 234, 0, 0, 40000, 433,0 }, + { 254, 255, 0, 0, 40000, 93,0 }, + { 192, 193, 0, 0, 40000, 66,0 }, + { 252, 253, 0, 0, 40000, 73,0 }, + { 248,3027, 0, 0, 40000, 80,0 }, + { 39,1476, 0, 0, 40000, 160,0 }, + { 241, 242, 0, 0, 40000, 146,0 }, + {1508,1509, 0, 0, 40000, 0,0 }, + { 246, 247, 0, 0, 3966, 800,0 }, + { 181,1451, 0, 0, 2153, 640,0 }, + { 209, 210, 0, 0, 4453, 100,0 }, + { 270, 271, 0, 0, 40000, 80,0 }, + { 115,1533, 0, 0, 4260, 1720,0 }, + {1454,1455, 0, 0, 40000, 0,0 }, + { 107, 319, 0, 0, 1266, 413,0 }, + { 46, 238, 0, 0, 6873, 1246,0 }, + { 216, 217, 0, 0, 4046, 100,0 }, + { 272, 273, 0, 0, 40000, 126,0 }, + {1445,3028, 0, 0, 9966, 386,0 }, + { 172, 173, 0, 0, 7340, 100,0 }, + { 174, 175, 0, 0, 6913, 100,0 }, + {1447,3029, 0, 0, 10306, 80,0 }, + {1452,3030, 0, 0, 9240, 240,0 }, + { 183, 184, 0, 0, 586, 253,0 }, + {1456,1457, 0, 0, 1386, 180,0 }, + {1458,1459, 0, 0, 40000, 60,0 }, + { 190,1460, 0, 0, 40000, 46,0 }, + {1462,1463, 0, 0, 40000, 340,0 }, + {1464,1465, 0, 0, 40000, 360,0 }, + { 195, 196, 0, 0, 40000, 66,0 }, + { 197, 198, 0, 0, 40000, 86,0 }, + { 199, 200, 0, 0, 40000, 60,0 }, + { 201, 202, 0, 0, 3713, 100,0 }, + { 203, 204, 0, 0, 14633, 126,0 }, + { 205, 206, 0, 0, 9440, 153,0 }, + { 214, 215, 0, 0, 17020, 100,0 }, + { 218, 219, 0, 0, 14000, 180,0 }, + { 220, 221, 0, 0, 2846, 100,0 }, + {1472,1473, 0, 0, 8066, 66,0 }, + {1474,1475, 0, 0, 8040, 93,0 }, + { 225, 226, 0, 0, 8066, 106,0 }, + { 229, 230, 0, 0, 40000, 160,0 }, + {1478,1479, 0, 0, 40000, 413,0 }, + { 50,1480, 0, 0, 40000, 393,0 }, + {1485,1486, 0, 0, 40000, 226,0 }, + { 258, 259, 0, 0, 40000, 73,0 }, + { 262, 263, 0, 0, 40000, 160,0 }, + { 264, 265, 0, 0, 40000, 160,0 }, + {1494,1495, 0, 0, 40000, 80,0 }, + {1496,1497, 0, 0, 40000, 73,0 }, + { 274, 275, 0, 0, 40000, 100,0 }, + {1499,1500, 0, 0, 40000, 73,0 }, + { 277, 278, 0, 0, 40000, 173,0 }, + { 279, 280, 0, 0, 40000, 160,0 }, + { 281, 282, 0, 0, 40000, 173,0 }, + {1501,1502, 0, 0, 40000, 146,0 }, + { 284, 285, 0, 0, 40000, 66,0 }, + { 286, 287, 0, 0, 40000, 86,0 }, + {1503,1504, 0, 0, 40000, 86,0 }, + {1505,1506, 0, 0, 40000, 73,0 }, + { 289, 290, 0, 0, 40000, 66,0 }, + { 291, 292, 0, 0, 40000, 160,0 }, + { 293, 294, 0, 0, 40000, 200,0 }, + { 86,1507, 0, 0, 40000, 80,0 }, + { 88, 297, 0, 0, 40000, 1346,0 }, + { 298, 299, 0, 0, 40000, 320,0 }, + { 300, 301, 0, 0, 40000, 1273,0 }, + {1514,1515, 0, 0, 40000, 100,0 }, + {1518,1519, 0, 0, 4733, 0,0 }, + {1520,1521, 0, 0, 40000, 440,0 }, + {1524,1525, 0, 0, 40000, 1180,0 }, + {1526,1527, 0, 0, 40000, 746,0 }, + {1528,1529, 0, 0, 40000, 920,0 }, + { 311, 312, 0, 0, 15306, 213,0 }, + { 313, 314, 0, 0, 7280, 340,0 }, + { 315, 316, 0, 0, 3693, 346,0 }, + { 317, 318, 0, 0, 13720, 4033,0 }, + { 108, 320, 0, 0, 40000, 66,0 }, + { 109, 321, 0, 0, 40000, 180,0 }, + { 322, 323, 0, 0, 40000, 73,0 }, + { 111,1530, 0, 0, 4053, 426,0 }, + { 324, 325, 0, 0, 626, 260,0 }, + { 326, 327, 0, 0, 1166, 400,0 }, + {1531,1532, 0, 0, 186, 340,0 }, + {1534,1535, 0, 0, 3240, 440,0 }, + { 330, 331, 0, 0, 1920, 360,0 }, + {1536,1537, 0, 0, 3020, 0,0 }, + {1538,1539, 0, 0, 1660, 846,0 }, + {1541, 339, 0, 0, 9213, 813,0 }, + {1542,1543, 0, 0, 993, 100,0 }, + {1544,3031, 0, 0, 860, 180,0 }, + {1546,3032, 0, 0, 40000, 80,0 }, + { 338, 339, 0, 0, 40000, 200,0 }, + { 340, 341, 0, 0, 40000, 0,0 }, + {1441,1442, 0, 0, 7393, 186,0 }, + { 207, 208, 0, 0, 14373, 126,0 }, + {1466,1467, 0, 0, 40000, 66,0 }, + {1468,1469, 0, 0, 40000, 46,0 }, + { 179, 180, 0, 0, 4080, 346,0 }, + {1449,1450, 0, 0, 8313, 3373,0 }, + { 35,1470, 0, 0, 40000, 0,0 }, + { 36,1471, 0, 0, 8093, 40,0 }, + { 235, 236, 0, 0, 2393, 333,0 }, + {1483,1484, 0, 0, 40000, 0,0 }, + { 55,1487, 0, 0, 40000, 80,0 }, + {1488,1489, 0, 0, 40000, 80,0 }, + {1492,1493, 0, 0, 40000, 66,0 }, + { 256, 257, 0, 0, 40000, 53,0 }, + { 260, 261, 0, 0, 40000, 86,0 }, + {1512,1513, 0, 0, 40000, 40,0 }, + {1510,1511, 0, 0, 40000, 80,0 }, + {1496,1498, 0, 0, 40000, 73,0 }, + { 295, 296, 0, 0, 40000, 340,0 }, + {1540, 339, 0, 0, 2466, 633,0 }, + { 398, 399, 35, 0, 1860, 226,0 }, + {1516,1517, 0, 0, 40000, 660,0 }, + {1550,3033, 35, 0, 213, 26,0 }, + {1556,1557, 35, 0, 1200, 426,0 }, + {1558,1559, 35, 0, 1173, 406,0 }, + {1570,1571, 35, 0, 1160, 140,0 }, + {1608,1609, 35, 0, 2100, 320,0 }, + {1595,1596, 35, 0, 220, 273,0 }, + { 159,1597, 35, 0, 220, 266,0 }, + {1610,1611, 35, 0, 220, 273,0 }, + { 397,1588, 35, 0, 253, 86,0 }, + {1606,1607, 35, 0, 133, 66,0 }, + { 145,1576, 35, 0, 180, 0,0 }, + {1612,1613, 35, 0, 526, 400,0 }, + {1577,1578, 35, 0, 506, 453,0 }, + {1614,1615, 35, 0, 773, 933,0 }, + { 305, 306, 0, 0, 40000, 1160,0 }, + {1522,1523, 0, 0, 40000, 0,0 }, + {1550,1551, 35, 0, 526, 146,0 }, + { 364, 365, 35, 0, 186, 20,0 }, + { 129,1549, 35, 0, 326, 133,0 }, + { 132,1552, 35, 0, 226, 113,0 }, + {1553,1554, 35, 0, 206, 73,0 }, + { 129,1548, 35, 0, 326, 133,0 }, + { 134,1555, 35, 0, 2580, 893,0 }, + {1560,1561, 35, 0, 600, 366,0 }, + {1562,1563, 35, 0, 40000, 0,0 }, + {1572,1573, 35, 0, 340, 133,0 }, + {1574,1575, 35, 0, 406, 226,0 }, + {1581,1582, 35, 0, 640, 213,0 }, + { 149,1583, 35, 0, 326, 20,0 }, + {1584,1585, 35, 0, 633, 240,0 }, + {1591,1592, 35, 0, 1226, 413,0 }, + {1568,1569, 35, 0, 1313, 460,0 }, + {1579,1580, 35, 0, 326, 0,0 }, + {1586,1587, 35, 0, 606, 220,0 }, + {1589,1590, 35, 0, 120, 86,0 }, + {1600,1601, 35, 0, 1326, 420,0 }, + {1602,1603, 35, 0, 706, 266,0 }, + {1604,1605, 35, 0, 4540, 1326,0 }, + { 391, 392, 35, 0, 360, 153,0 }, + { 391, 393, 35, 0, 453, 153,0 }, + {1598,1599, 35, 0, 1246, 346,0 }, + { 367, 368, 35, 0, 600, 153,0 }, + { 380, 381, 35, 0, 40000, 0,0 }, + { 374, 375, 35, 0, 40000, 0,0 }, + {1566,1567, 35, 0, 40000, 0,0 }, + {2306,2307, 35, 0, 7660, 1560,0 }, + {3034, 339, 35, 0, 5860, 426,0 }, + {2301,2302, 35, 0, 2146, 753,0 }, + {2305,1548, 35, 0, 326, 133,0 }, + {1595,1595, 35, 0, 220, 273,0 }, + {2303,2304, 35, 0, 186, 20,0 }, + {1560,2308, 35, 0, 600, 373,0 }, + {2309,2310, 35, 0, 40000, 0,0 }, + {1568,1568, 35, 0, 1280, 453,0 }, + {2311,2312, 35, 0, 360, 106,0 }, + {2313,2314, 35, 0, 620, 0,0 }, + {2315,2315, 35, 0, 106, 0,0 }, + {2316,2316, 35, 0, 506, 453,0 }, + {1612,1612, 35, 0, 526, 400,0 }, + {2317,2317, 35, 0, 640, 253,0 }, + {2318,2318, 35, 0, 326, 20,0 }, + {2319,2319, 35, 0, 453, 446,0 }, + {2320,2320, 35, 0, 466, 453,0 }, + {2321,2321, 35, 0, 120, 26,0 }, + {2322,2322, 35, 0, 1220, 406,0 }, + {2323,2323, 35, 0, 2360, 786,0 }, + {2324, 392, 35, 0, 353, 146,0 }, + {2324, 393, 35, 0, 453, 146,0 }, + {2325,2326, 35, 0, 533, 140,0 }, + {2327,2328, 35, 0, 1273, 393,0 }, + {2329,2330, 35, 0, 40000, 0,0 }, + {2331,2332, 35, 0, 40000, 0,0 }, + {3035,3036, 35, 0, 4133, 433,0 }, + {3037,3038, 35, 0, 1740, 286,0 }, + {1564,1564, 35, 0, 713, 273,0 }, + {3039,3039, 0, 0, 40000, 0,0 }, + {3040,3040, 0, 0, 6100, 146,0 }, + {3041,3041, 0, 0, 2386, 26,0 }, + {3042,3042, 0, 0, 4320, 80,0 }, + {3043,3043, 0, 0, 3433, 313,0 }, + {3044,3044, 0, 0, 6620, 2446,0 }, + {3045,3045, 0, 0, 3726, 1253,0 }, + {3046,3046, 0, 0, 40000, 133,0 }, + {3047,3047, 0, 0, 4566, 1253,0 }, + {3048,3048, 0, 0, 40000, 813,0 }, + {3049,3049, 0, 0, 18513, 1560,0 }, + {3050,3050, 0, 0, 2186, 426,0 }, + {3051,3051, 0, 0, 1186, 420,0 }, + {3052,3052, 0, 0, 766, 420,0 }, + {3053,3053, 0, 0, 14513, 4713,0 }, + {3054,3054, 0, 0, 15493, 1580,0 }, + {3055,3055, 0, 0, 40000, 66,0 }, + {3056,3056, 0, 0, 40000, 60,0 }, + {3057,3057, 0, 0, 4740, 100,0 }, + {3058,3058, 0, 0, 40000, 66,0 }, + {3059,3059, 0, 0, 40000, 73,0 }, + {3060,3060, 0, 0, 40000, 73,0 }, + {3061,3061, 0, 0, 40000, 0,0 }, + {3062,3062, 0, 0, 8373, 633,0 }, + {3063,3063, 0, 0, 7560, 133,0 }, + {3064,3064, 0, 0, 40000, 0,0 }, + {3065,3065, 0, 0, 40000, 86,0 }, + {3066,3066, 0, 0, 340, 140,0 }, + {3067,3067, 0, 0, 40000, 0,0 }, + {3068,3068, 0, 0, 40000, 166,0 }, + {3069,3069, 0, 0, 4280, 1466,0 }, + {3070,3070, 0, 0, 2193, 73,0 }, + {3071,3071, 0, 0, 4846, 100,0 }, + {3072,3072, 0, 0, 12740, 93,0 }, + {3073,3073, 0, 0, 6953, 200,0 }, + {3074,3074, 0, 0, 13780, 73,0 }, + {3075,3075, 0, 0, 40000, 73,0 }, + {3076,3076, 0, 0, 5860, 600,0 }, + {3077,3077, 0, 0, 2206, 73,0 }, + {3078,3078, 0, 0, 40000, 140,0 }, + {3079,3079, 0, 0, 40000, 53,0 }, + {3080,3080, 0, 0, 40000, 120,0 }, + {3081,3081, 0, 0, 40000, 140,0 }, + {3082,3082, 0, 0, 40000, 126,0 }, + {3083,3083, 0, 0, 360, 140,0 }, + {3084,3084, 0, 0, 8880, 1373,0 }, + {3085,3085, 0, 0, 593, 73,0 }, + {3086,3086, 0, 0, 40000, 193,0 }, + {3087,3087, 0, 0, 40000, 200,0 }, + {3088,3088, 0, 0, 40000, 160,0 }, + {3089,3089, 0, 0, 40000, 200,0 }, + {3090,3090, 0, 0, 40000, 53,0 }, + {3091,3091, 0, 0, 40000, 73,0 }, + {3092,3092, 0, 0, 40000, 73,0 }, + {3093,3093, 0, 0, 760, 213,0 }, + {3094,3094, 0, 0, 40000, 133,0 }, + {3095,3095, 0, 0, 40000, 220,0 }, + {3096,3096, 0, 0, 40000, 100,0 }, + {3097,3097, 0, 0, 40000, 73,0 }, + {3098,3098, 0, 0, 40000, 140,0 }, + {3099,3099, 0, 0, 40000, 140,0 }, + {3100,3100, 0, 0, 40000, 140,0 }, + {3101,3101, 0, 0, 40000, 73,0 }, + {3102,3102, 0, 0, 40000, 73,0 }, + {3103,3103, 0, 0, 40000, 73,0 }, + {3104,3104, 0, 0, 40000, 73,0 }, + {3105,3105, 0, 0, 40000, 66,0 }, + {3106,3106, 0, 0, 40000, 66,0 }, + {3107,3107, 0, 0, 40000, 73,0 }, + {3108,3108, 0, 0, 40000, 73,0 }, + {3109,3109, 0, 0, 40000, 73,0 }, + {3110,3110, 0, 0, 40000, 73,0 }, + {3111,3111, 0, 0, 40000, 86,0 }, + {3112,3112, 0, 0, 5393, 100,0 }, + {3113,3113, 0, 0, 40000, 60,0 }, + {3114,3114, 0, 0, 18500, 73,0 }, + {3115,3115, 0, 0, 40000, 93,0 }, + {3116,3116, 0, 0, 40000, 86,0 }, + {3117,3117, 0, 0, 40000, 173,0 }, + {3118,3118, 0, 0, 40000, 1353,0 }, + {3119,3119, 0, 0, 17506, 73,0 }, + {3120,3120, 0, 0, 40000, 100,0 }, + {3121,3121, 0, 0, 40000, 73,0 }, + {3122,3122, 0, 0, 5620, 193,0 }, + {3123,3123, 0, 0, 3700, 80,0 }, + {3124,3124, 0, 0, 40000, 66,0 }, + {3125,3125, 0, 0, 2740, 80,0 }, + {3126,3126, 0, 0, 8333, 173,0 }, + {3127,3127, 0, 0, 2226, 466,0 }, + {3128,3128, 0, 0, 340, 146,0 }, + {3129,3129, 0, 0, 19980, 6280,0 }, + {3130,3130, 0, 0, 353, 73,0 }, + {3131,3131, 35, 0, 566, 233,0 }, + {3132,3132, 35, 0, 226, 46,0 }, + {3133,3133, 35, 0, 40000, 100,0 }, + {3134,3134, 35, 0, 40000, 100,0 }, + {3135,3135, 35, 0, 360, 146,0 }, + {3061,3061, 35, 0, 40000, 0,0 }, + {3136,3136, 35, 0, 366, 20,0 }, + { 739, 739, 35, 0, 246, 20,0 }, + {3137,3137, 35, 0, 333, 33,0 }, + {3138,3138, 35, 0, 420, 166,0 }, + {3139,3139, 35, 0, 626, 240,0 }, + {3140,3140, 35, 0, 233, 100,0 }, + {3141,3141, 35, 0, 1166, 440,0 }, + {3142,3142, 35, 0, 166, 66,0 }, + {3143,3143, 35, 0, 1166, 440,0 }, + {3144,3144, 35, 0, 813, 100,0 }, + {3145,3145, 35, 0, 1040, 440,0 }, + {3146,3146, 35, 0, 40000, 0,0 }, + {3147,3147, 35, 0, 40000, 0,0 }, + {3148,3148, 35, 0, 180, 40,0 }, + {3149,3149, 35, 0, 40000, 0,0 }, + {3150,3150, 0, 0, 40000, 0,0 }, + {3151,3151, 0, 0, 4900, 240,0 }, + {3152,3152, 0, 0, 3480, 80,0 }, + {3153,3153, 0, 0, 3586, 86,0 }, + {3154,3154, 0, 0, 4626, 633,0 }, + {3155,3155, 0, 0, 4293, 2286,0 }, + {3156,3156, 0, 0, 13653, 0,0 }, + {3157,3157, 0, 0, 1206, 426,0 }, + {3158,3158, 0, 0, 653, 426,0 }, + {3159,3159, 0, 0, 40000, 0,0 }, + {3160,3160, 0, 0, 4633, 633,0 }, + {3161,3161, 0, 0, 40000, 73,0 }, + {3162,3162, 0, 0, 40000, 60,0 }, + {3163,3163, 0, 0, 40000, 146,0 }, + {3164,3164, 0, 0, 40000, 73,0 }, + {3165,3165, 0, 0, 40000, 73,0 }, + {3166,3166, 0, 0, 40000, 0,0 }, + {3167,3167, 0, 0, 40000, 66,0 }, + {3168,3168, 0, 0, 3680, 1180,0 }, + {3169,3169, 0, 0, 2406, 846,0 }, + {3170,3170, 0, 0, 1560, 73,0 }, + {3171,3171, 0, 0, 1946, 226,0 }, + {3172,3172, 0, 0, 4333, 13,0 }, + {3173,3173, 0, 0, 40000, 0,0 }, + {3174,3174, 0, 0, 40000, 0,0 }, + {3175,3175, 0, 0, 40000, 66,0 }, + {3176,3176, 0, 0, 40000, 180,0 }, + {3177,3177, 0, 0, 15380, 80,0 }, + {3178,3178, 0, 0, 18213, 73,0 }, + {3179,3179, 0, 0, 1706, 0,0 }, + {3180,3180, 0, 0, 5733, 1266,0 }, + {3181,3181, 0, 0, 40000, 0,0 }, + {3182,3182, 0, 0, 40000, 366,0 }, + {3183,3183, 0, 0, 40000, 66,0 }, + {3184,3184, 0, 0, 4786, 73,0 }, + {3185,3185, 0, 0, 5660, 720,0 }, + {3186,3186, 0, 0, 1293, 406,0 }, + {3187,3187, 0, 0, 40000, 0,0 }, + {3188,3188, 0, 0, 2686, 233,0 }, + {3189,3189, 0, 0, 40000, 0,0 }, + {3190,3190, 0, 0, 40000, 73,0 }, + {3191,3191, 0, 0, 40000, 0,0 }, + {3192,3192, 0, 0, 40000, 73,0 }, + {3193,3193, 0, 0, 40000, 0,0 }, + {3194,3194, 0, 0, 3920, 73,0 }, + {3195,3195, 0, 0, 40000, 73,0 }, + {3196,3196, 0, 0, 40000, 66,0 }, + {3197,3197, 0, 0, 40000, 80,0 }, + {3198,3198, 0, 0, 40000, 86,0 }, + {3199,3199, 0, 0, 40000, 60,0 }, + {3200,3200, 0, 0, 40000, 0,0 }, + {3201,3201, 0, 0, 40000, 353,0 }, + {3202,3202, 0, 0, 3920, 73,0 }, + {3203,3203, 0, 0, 5833, 813,0 }, + {3204,3204, 0, 0, 40000, 60,0 }, + {3205,3205, 0, 0, 40000, 73,0 }, + {3206,3206, 0, 0, 1400, 406,0 }, + {3207,3207, 0, 0, 40000, 66,0 }, + {3208,3208, 0, 0, 9066, 2220,0 }, + {3209,3209, 0, 0, 1473, 773,0 }, + {3210,3210, 0, 0, 40000, 120,0 }, + {3211,3211, 0, 0, 40000, 306,0 }, + {3212,3212, 0, 0, 9306, 3013,0 }, + {3213,3213, 0, 0, 40000, 60,0 }, + {3214,3214, 0, 0, 40000, 73,0 }, + {3215,3215, 0, 0, 40000, 73,0 }, + {3216,3216, 0, 0, 40000, 453,0 }, + {3217,3217, 0, 0, 40000, 3460,0 }, + {3218,3218, 0, 0, 40000, 453,0 }, + {3219,3219, 0, 0, 40000, 40,0 }, + {3220,3220, 0, 0, 40000, 3926,0 }, + {3221,3221, 0, 0, 40000, 4506,0 }, + {3222,3222, 0, 0, 4646, 646,0 }, + {3223,3223, 0, 0, 773, 100,0 }, + {3224,3224, 0, 0, 40000, 73,0 }, + {3225,3225, 0, 0, 40000, 173,0 }, + {3226,3226, 0, 0, 1606, 653,0 }, + {3227,3227, 0, 0, 2353, 806,0 }, + {3228,3228, 0, 0, 980, 360,0 }, + {3229,3229, 0, 0, 1193, 413,0 }, + { 499, 499, 0, 0, 266, 0,0 }, + {3230,3230, 0, 0, 973, 360,0 }, + {3231,3231, 0, 0, 273, 53,0 }, + {3232,3232, 0, 0, 726, 220,0 }, + {3233,3233, 0, 0, 19933, 6093,0 }, + {3234,3234, 0, 0, 40000, 0,0 }, + { 403, 403, 0, 0, 40000, 73,0 }, + {3235,3235, 0, 0, 4966, 233,0 }, + {3236,3236, 0, 0, 4946, 240,0 }, + {3237,3237, 0, 0, 4946, 233,0 }, + {3238,3238, 0, 0, 4640, 1613,0 }, + {3239,3239, 0, 0, 2360, 806,0 }, + {3240,3240, 0, 0, 4466, 200,0 }, + {3241,3241, 0, 0, 40000, 73,0 }, + {3242,3242, 0, 0, 40000, 73,0 }, + {3243,3243, 0, 0, 40000, 73,0 }, + {3244,3244, 0, 0, 40000, 73,0 }, + {3245,3245, 0, 0, 40000, 240,0 }, + {3246,3246, 0, 0, 40000, 226,0 }, + {3247,3247, 0, 0, 40000, 233,0 }, + {3248,3248, 0, 0, 40000, 240,0 }, + {3249,3249, 0, 0, 4306, 1253,0 }, + {3250,3250, 0, 0, 3873, 1206,0 }, + {3251,3251, 0, 0, 4640, 633,0 }, + {3252,3252, 0, 0, 1233, 80,0 }, + {3253,3253, 0, 0, 1233, 26,0 }, + {3254,3254, 0, 0, 1233, 26,0 }, + {3255,3255, 0, 0, 4573, 1253,0 }, + {3256,3256, 0, 0, 3793, 1240,0 }, + {3257,3257, 0, 0, 40000, 73,0 }, + {3258,3258, 0, 0, 40000, 73,0 }, + {3259,3259, 0, 0, 40000, 140,0 }, + {3260,3260, 0, 0, 40000, 146,0 }, + {3261,3261, 0, 0, 40000, 80,0 }, + {3262,3262, 0, 0, 5953, 200,0 }, + {3263,3263, 0, 0, 5926, 200,0 }, + {3264,3264, 0, 0, 5866, 26,0 }, + {3265,3265, 0, 0, 18573, 6153,0 }, + {3266,3266, 0, 0, 40000, 2093,0 }, + {3267,3267, 0, 0, 40000, 73,0 }, + {3268,3268, 0, 0, 18626, 1553,0 }, + {3269,3269, 0, 0, 40000, 1820,0 }, + {3270,3270, 0, 0, 40000, 500,0 }, + {3271,3271, 0, 0, 18206, 5900,0 }, + {3272,3272, 0, 0, 14200, 93,0 }, + {3273,3273, 0, 0, 40000, 2873,0 }, + {3274,3274, 0, 0, 14960, 4913,0 }, + {3275,3275, 0, 0, 40000, 86,0 }, + {3276,3276, 0, 0, 40000, 826,0 }, + {3277,3277, 0, 0, 40000, 200,0 }, + {3278,3278, 0, 0, 40000, 340,0 }, + {3279,3279, 0, 0, 13220, 2500,0 }, + {3280,3280, 0, 0, 40000, 100,0 }, + {3281,3281, 0, 0, 40000, 1026,0 }, + {3282,3282, 0, 0, 40000, 366,0 }, + {3283,3283, 0, 0, 40000, 386,0 }, + {3284,3284, 0, 0, 40000, 0,0 }, + {3285,3285, 0, 0, 40000, 0,0 }, + {3286,3286, 0, 0, 40000, 140,0 }, + {3287,3287, 0, 0, 40000, 53,0 }, + {3288,3288, 0, 0, 40000, 120,0 }, + {3289,3289, 0, 0, 8866, 1366,0 }, + {3290,3290, 0, 0, 4193, 1400,0 }, + {3291,3291, 0, 0, 8353, 673,0 }, + {3292,3292, 0, 0, 8353, 673,0 }, + {3293,3293, 0, 0, 8400, 593,0 }, + {3294,3294, 0, 0, 8440, 666,0 }, + {3295,3295, 0, 0, 9600, 1580,0 }, + {3296,3296, 0, 0, 40000, 46,0 }, + {3297,3297, 0, 0, 40000, 0,0 }, + {3298,3298, 0, 0, 1653, 93,0 }, + {3299,3299, 0, 0, 2706, 73,0 }, + {3300,3300, 0, 0, 11680, 26,0 }, + {3301,3301, 0, 0, 6500, 340,0 }, + {3302,3302, 0, 0, 40000, 0,0 }, + {3303,3303, 0, 0, 40000, 0,0 }, + {3304,3304, 0, 0, 40000, 73,0 }, + {3305,3305, 0, 0, 40000, 73,0 }, + {3306,3306, 0, 0, 40000, 73,0 }, + {3307,3307, 0, 0, 40000, 73,0 }, + {3308,3308, 0, 0, 40000, 73,0 }, + {3309,3309, 0, 0, 40000, 73,0 }, + {3310,3310, 0, 0, 40000, 73,0 }, + {3311,3311, 0, 0, 40000, 73,0 }, + {3312,3312, 0, 0, 40000, 73,0 }, + {3313,3313, 0, 0, 40000, 133,0 }, + {3314,3314, 0, 0, 40000, 126,0 }, + {3315,3315, 0, 0, 40000, 73,0 }, + {3316,3316, 0, 0, 40000, 73,0 }, + {3317,3317, 0, 0, 40000, 73,0 }, + {3318,3318, 0, 0, 40000, 200,0 }, + {3319,3319, 0, 0, 40000, 133,0 }, + {3320,3320, 0, 0, 40000, 0,0 }, + {3321,3321, 0, 0, 40000, 240,0 }, + {3322,3322, 0, 0, 40000, 220,0 }, + {3323,3323, 0, 0, 40000, 226,0 }, + {3324,3324, 0, 0, 40000, 100,0 }, + {3325,3325, 0, 0, 40000, 140,0 }, + {3326,3326, 0, 0, 40000, 0,0 }, + {3327,3327, 0, 0, 40000, 426,0 }, + {3328,3328, 0, 0, 40000, 426,0 }, + {3329,3329, 0, 0, 3680, 1220,0 }, + {3330,3330, 0, 0, 40000, 533,0 }, + {3331,3331, 0, 0, 40000, 813,0 }, + {3332,3332, 0, 0, 14506, 4706,0 }, + {3333,3333, 0, 0, 766, 420,0 }, + {3334,3334, 0, 0, 40000, 1566,0 }, + {3335,3335, 0, 0, 40000, 120,0 }, + {3336,3336, 0, 0, 40000, 2380,0 }, + {3337,3337, 0, 0, 5666, 300,0 }, + {3338,3338, 0, 0, 40000, 73,0 }, + {3339,3339, 0, 0, 40000, 2513,0 }, + {3340,3340, 0, 0, 1260, 826,0 }, + {3341,3341, 0, 0, 2420, 413,0 }, + {3342,3342, 0, 0, 626, 240,0 }, + {3343,3343, 0, 0, 273, 60,0 }, + {3344,3344, 0, 0, 540, 20,0 }, + {3345,3345, 0, 0, 540, 20,0 }, + {3346,3346, 0, 0, 540, 20,0 }, + {3347,3347, 0, 0, 1153, 760,0 }, + {3348,3348, 0, 0, 40000, 100,0 }, + {3349,3349, 0, 0, 7326, 2380,0 }, + {3350,3350, 0, 0, 40000, 4426,0 }, + {3351,3351, 0, 0, 7413, 2493,0 }, + {3352,3352, 0, 0, 253, 20,0 }, + {3353,3353, 0, 0, 246, 33,0 }, + {3354,3354, 0, 0, 286, 13,0 }, + {3355,3355, 0, 0, 953, 13,0 }, + {3356,3356, 0, 0, 293, 20,0 }, + { 142, 142, 20, 0, 1893, 620,0 }, + {3357,1451, 0, 4, 2373, 780,0 }, + {3358,3359, 0, 4, 9260, 246,0 }, + {3360,1455, 0, 4, 40000, 0,0 }, + {3361,1463, 0, 4, 40000, 266,0 }, + { 225,3362, 0, 4, 7993, 100,0 }, + {3363,1545, 0, 4, 293, 86,0 }, + {3364,1547, 0, 4, 40000, 180,0 }, + {3365,3366, 39, 4, 66, 0,0 }, + {3367, 368, 58, 4, 173, 0,0 }, + {3368,1551, 48, 4, 520, 200,0 }, + {3368,3033, 49, 4, 53, 0,0 }, + {3368,3033, 51, 4, 53, 0,0 }, + {3368,3033, 54, 4, 60, 0,0 }, + {3368,3033, 57, 4, 60, 0,0 }, + {3368,3033, 60, 4, 60, 0,0 }, + {3369,3370, 70, 4, 840, 0,0 }, + {1564,1565, 80, 4, 220, 0,0 }, + {3371,1571, 44, 4, 420, 0,0 }, + {3372,3372, 0, 0, 8366, 666,0 }, + {3373,3373, 0, 0, 8366, 666,0 }, + {3374,3374, 0, 0, 3773, 73,0 }, + {3375,3375, 0, 0, 8366, 666,0 }, + {3376,3376, 0, 0, 4693, 26,0 }, + {3377,3377, 0, 0, 7400, 80,0 }, + {3378,3378, 0, 0, 3586, 80,0 }, + {3379,3379, 0, 0, 8366, 666,0 }, + {3380,3380, 0, 0, 3786, 1240,0 }, + {3381,3381, 0, 0, 9013, 1466,0 }, + {3382,3382, 0, 0, 1200, 73,0 }, + {3383,3383, 0, 0, 8146, 1446,0 }, + {3384,3384, 0, 0, 3660, 1206,0 }, + {3385,3385, 0, 0, 200, 100,0 }, + {3386,3386, 0, 0, 40000, 0,0 }, + {3387,3387, 0, 0, 1213, 426,0 }, + {3388,3388, 0, 0, 40000, 2573,0 }, + {3389,3389, 0, 0, 40000, 3446,0 }, + {3390,3390, 0, 0, 40000, 333,0 }, + {3391,3391, 0, 0, 40000, 73,0 }, + {3392,3392, 0, 0, 40000, 93,0 }, + {3393,3393, 0, 0, 40000, 73,0 }, + {3394,3394, 0, 0, 40000, 73,0 }, + {3395,3395, 0, 0, 40000, 73,0 }, + {3396,3396, 0, 0, 2193, 413,0 }, + {3397,3397, 0, 0, 14606, 2886,0 }, + {3398,3398, 0, 0, 10626, 4520,0 }, + {3399,3399, 0, 0, 2413, 100,0 }, + {3400,3400, 0, 0, 3593, 1140,0 }, + {3401,3401, 0, 0, 40000, 146,0 }, + {3402,3402, 0, 0, 40000, 86,0 }, + {3403,3403, 0, 0, 40000, 86,0 }, + {3404,3404, 0, 0, 9366, 106,0 }, + {3405,3405, 0, 0, 40000, 73,0 }, + {3406,3406, 0, 0, 40000, 0,0 }, + {3407,3407, 0, 0, 40000, 0,0 }, + {3408,3408, 0, 0, 1626, 400,0 }, + {3409,3409, 0, 0, 4473, 2933,0 }, + {3410,3410, 0, 0, 40000, 66,0 }, + {3411,3411, 0, 0, 40000, 0,0 }, + {3412,3412, 0, 0, 40000, 253,0 }, + {3413,3413, 0, 0, 40000, 233,0 }, + {3414,3414, 0, 0, 40000, 346,0 }, + {3415,3415, 0, 0, 1966, 26,0 }, + {3416,3416, 0, 0, 40000, 366,0 }, + {3417,3417, 0, 0, 2266, 386,0 }, + {3418,3418, 0, 0, 40000, 0,0 }, + {3419,3419, 0, 0, 2313, 766,0 }, + {3420,3420, 0, 0, 40000, 340,0 }, + {3421,3421, 0, 0, 40000, 346,0 }, + {3422,3422, 0, 0, 40000, 340,0 }, + {3423,3423, 0, 0, 40000, 353,0 }, + {3424,3424, 0, 0, 40000, 353,0 }, + {3425,3425, 0, 0, 40000, 226,0 }, + {3426,3426, 0, 0, 40000, 73,0 }, + {3427,3427, 0, 0, 940, 253,0 }, + {3428,3428, 0, 0, 40000, 73,0 }, + {3429,3429, 0, 0, 40000, 80,0 }, + {3430,3430, 0, 0, 40000, 240,0 }, + {3431,3431, 0, 0, 40000, 80,0 }, + {3432,3432, 0, 0, 40000, 73,0 }, + {3433,3433, 0, 0, 40000, 73,0 }, + {3434,3434, 0, 0, 40000, 73,0 }, + {3435,3435, 0, 0, 40000, 73,0 }, + {3436,3436, 0, 0, 40000, 73,0 }, + {3437,3437, 0, 0, 40000, 73,0 }, + {3438,3438, 0, 0, 40000, 73,0 }, + {3439,3439, 0, 0, 40000, 73,0 }, + {3440,3440, 0, 0, 40000, 73,0 }, + {3441,3441, 0, 0, 40000, 73,0 }, + {3442,3442, 0, 0, 40000, 66,0 }, + {3443,3443, 0, 0, 40000, 73,0 }, + {3444,3444, 0, 0, 40000, 80,0 }, + {3445,3445, 0, 0, 40000, 66,0 }, + {3446,3446, 0, 0, 40000, 66,0 }, + {3447,3447, 0, 0, 40000, 66,0 }, + {3448,3448, 0, 0, 40000, 66,0 }, + {3449,3449, 0, 0, 40000, 80,0 }, + {3450,3450, 0, 0, 40000, 353,0 }, + {3451,3451, 0, 0, 40000, 0,0 }, + {3452,3452, 0, 0, 18440, 100,0 }, + {3453,3453, 0, 0, 18086, 100,0 }, + {3454,3454, 0, 0, 266, 66,0 }, + {3455,3455, 0, 0, 40000, 80,0 }, + {3456,3456, 0, 0, 40000, 100,0 }, + {3457,3457, 0, 0, 40000, 80,0 }, + {3458,3458, 0, 0, 40000, 120,0 }, + {3459,3459, 0, 0, 40000, 93,0 }, + {3460,3460, 0, 0, 40000, 233,0 }, + {3461,3461, 0, 0, 40000, 0,0 }, + {3462,3462, 0, 0, 40000, 86,0 }, + {3463,3463, 0, 0, 40000, 820,0 }, + {3464,3464, 0, 0, 40000, 4986,0 }, + {3465,3465, 0, 0, 40000, 146,0 }, + {3466,3466, 0, 0, 40000, 100,0 }, + {3467,3467, 0, 0, 40000, 3346,0 }, + {3468,3468, 0, 0, 40000, 660,0 }, + {3469,3469, 0, 0, 40000, 366,0 }, + {3470,3470, 0, 0, 40000, 1480,0 }, + {3471,3471, 0, 0, 40000, 646,0 }, + {3472,3472, 0, 0, 40000, 2673,0 }, + {3473,3473, 0, 0, 40000, 2500,0 }, + {3474,3474, 0, 0, 40000, 2513,0 }, + {3475,3475, 0, 0, 40000, 66,0 }, + {3476,3476, 0, 0, 9600, 1580,0 }, + {3477,3477, 0, 0, 40000, 46,0 }, + {3478,3478, 0, 0, 10673, 100,0 }, + {3479,3479, 0, 0, 2333, 800,0 }, + {3480,3480, 0, 0, 3673, 1200,0 }, + {3481,3481, 0, 0, 40000, 73,0 }, + {3482,3482, 0, 0, 40000, 146,0 }, + {3483,3483, 0, 0, 40000, 73,0 }, + {3484,3484, 0, 0, 2266, 726,0 }, + {3485,3485, 0, 0, 333, 140,0 }, + {3486,3486, 0, 0, 2286, 746,0 }, + {3487,3487, 0, 0, 293, 126,0 }, + {3488,3488, 0, 0, 3700, 1213,0 }, + {3489,3489, 0, 0, 3773, 1186,0 }, + {3490,3490, 0, 0, 3646, 1200,0 }, + {3491,3491, 0, 0, 3020, 73,0 }, + {3492,3492, 0, 0, 786, 273,0 }, + {3493,3493, 0, 0, 40000, 146,0 }, + {3494,3494, 0, 0, 40000, 3093,0 }, + {3495,3495, 0, 0, 273, 60,0 }, + {3496,3496, 0, 0, 40000, 73,0 }, + {3497,3497, 0, 0, 40000, 73,0 }, + {3498,3498, 0, 0, 40000, 3093,0 }, + {3499,3499, 0, 0, 40000, 240,0 }, + {3500,3500, 0, 2, 6, 0,0 }, + { 739, 739, 46, 0, 220, 33,0 }, + {3501,3501, 47, 0, 973, 93,0 }, + {3502,3502, 64, 0, 126, 66,0 }, + {3503,3503, 40, 0, 340, 146,0 }, + {3504,3504, 48, 0, 100, 0,0 }, + {3505,3505, 48, 0, 286, 133,0 }, + {3506,3506, 46, 0, 466, 166,0 }, + {3507,3507,111, 0, 226, 113,0 }, + {3508,3508, 49, 0, 473, 166,0 }, + {3509,3509, 56, 0, 126, 40,0 }, + {3510,3510, 52, 0, 520, 206,0 }, + {3511,3511, 96, 0, 1346, 473,0 }, + {3510,3510, 54, 0, 513, 206,0 }, + {3512,3512, 57, 0, 973, 266,0 }, + {3513,3513, 82, 0, 1580, 553,0 }, + {3510,3510, 60, 0, 506, 200,0 }, + {3514,3514, 60, 0, 1886, 646,0 }, + {3515,3515, 92, 0, 1026, 520,0 }, + {3516,3516, 60, 0, 180, 93,0 }, + {3517,3517, 58, 0, 213, 213,0 }, + {3518,3518, 22, 0, 2300, 766,0 }, + {3519,3519, 60, 0, 1873, 653,0 }, + {3520,3520, 72, 0, 260, 93,0 }, + {3521,3521, 77, 0, 253, 93,0 }, + {3522,3522, 70, 0, 206, 93,0 }, + {3523,3523, 75, 0, 173, 93,0 }, + {3524,3524, 69, 0, 406, 113,0 }, + {3525,3525, 59, 0, 380, 160,0 }, + {3526,3526, 48, 0, 373, 40,0 }, + {3527,3527, 89, 0, 433, 180,0 }, + {3528,3528, 84, 0, 813, 180,0 }, + {3529,3529, 33, 0, 240, 53,0 }, + {3530,3530, 55, 0, 220, 86,0 }, + {3531,3531, 58, 0, 526, 200,0 }, + {3532,3532, 52, 0, 526, 193,0 }, + {3533,3533, 57, 0, 166, 80,0 }, + {3534,3534, 57, 0, 240, 100,0 }, + {3535,3535, 85, 0, 220, 113,0 }, + {3536,3536, 68, 0, 173, 93,0 }, + {3536,3536, 61, 0, 220, 113,0 }, + {3537,3537, 64, 0, 346, 53,0 }, + {3538,3538, 44, 0, 1080, 346,0 }, + {3539,3539,100, 0, 193, 20,0 }, + {3540,3540,100, 0, 793, 26,0 }, + {3541,3541, 0, 0, 14166, 320,0 }, + {3542,3542, 0, 0, 3873, 1613,0 }, + {3543,3543, 0, 0, 3586, 86,0 }, + {3544,3544, 0, 0, 7406, 2486,0 }, + {3545,3545, 0, 0, 4640, 1560,0 }, + {3546,3546, 0, 0, 446, 440,0 }, + {3547,3547, 0, 0, 9253, 3100,0 }, + {3548,3548, 0, 0, 4646, 646,0 }, + {3549,3549, 0, 0, 40000, 66,0 }, + {3550,3550, 0, 0, 40000, 73,0 }, + {3551,3551, 0, 0, 40000, 113,0 }, + {3552,3552, 0, 0, 40000, 73,0 }, + {3553,3553, 0, 0, 40000, 73,0 }, + {3554,3554, 0, 0, 40000, 0,0 }, + {3555,3555, 0, 0, 40000, 60,0 }, + {3556,3556, 0, 0, 3673, 1206,0 }, + {3557,3557, 0, 0, 3706, 1293,0 }, + {3558,3558, 0, 0, 5693, 1126,0 }, + {3559,3559, 0, 0, 2406, 846,0 }, + {3560,3560, 0, 0, 40000, 66,0 }, + {3561,3561, 0, 0, 40000, 73,0 }, + {3562,3562, 0, 0, 4333, 13,0 }, + {3563,3563, 0, 0, 3700, 66,0 }, + {3564,3564, 0, 0, 40000, 0,0 }, + {3565,3565, 0, 0, 3713, 1260,0 }, + {3566,3566, 0, 0, 1140, 126,0 }, + {3567,3567, 0, 0, 40000, 186,0 }, + {3568,3568, 0, 0, 40000, 0,0 }, + {3569,3569, 0, 0, 14400, 6,0 }, + {3570,3570, 0, 0, 14580, 66,0 }, + {3571,3571, 0, 0, 40000, 73,0 }, + {3572,3572, 0, 0, 40000, 353,0 }, + {3573,3573, 0, 0, 40000, 0,0 }, + {3574,3574, 0, 0, 40000, 173,0 }, + {3575,3575, 0, 0, 1833, 600,0 }, + {3576,3576, 0, 0, 40000, 0,0 }, + {3577,3577, 0, 0, 40000, 206,0 }, + {3578,3578, 0, 0, 40000, 46,0 }, + {3579,3579, 0, 0, 40000, 73,0 }, + {3580,3580, 0, 0, 9166, 2900,0 }, + {3581,3581, 0, 0, 5640, 680,0 }, + {3582,3582, 0, 0, 640, 220,0 }, + {3583,3583, 0, 0, 40000, 53,0 }, + {3584,3584, 0, 0, 40000, 26,0 }, + {3585,3585, 0, 0, 40000, 0,0 }, + {3586,3586, 0, 0, 40000, 66,0 }, + {3587,3587, 0, 0, 40000, 60,0 }, + {3588,3588, 0, 0, 40000, 0,0 }, + {3589,3589, 0, 0, 40000, 73,0 }, + {3590,3590, 0, 0, 40000, 0,0 }, + {3591,3591, 0, 0, 40000, 0,0 }, + {3592,3592, 0, 0, 3780, 73,0 }, + {3593,3593, 0, 0, 40000, 0,0 }, + {3594,3594, 0, 0, 3786, 73,0 }, + {3595,3595, 0, 0, 40000, 73,0 }, + {3596,3596, 0, 0, 40000, 66,0 }, + {3597,3597, 0, 0, 40000, 73,0 }, + {3598,3598, 0, 0, 40000, 53,0 }, + {3599,3599, 0, 0, 40000, 426,0 }, + {3600,3600, 0, 0, 40000, 133,0 }, + {3601,3601, 0, 0, 40000, 66,0 }, + {3602,3602, 0, 0, 40000, 433,0 }, + {3603,3603, 0, 0, 393, 126,0 }, + {3604,3604, 0, 0, 40000, 66,0 }, + {3605,3605, 0, 0, 40000, 353,0 }, + {3606,3606, 0, 0, 3813, 73,0 }, + {3607,3607, 0, 0, 5793, 780,0 }, + {3608,3608, 0, 0, 40000, 73,0 }, + {3609,3609, 0, 0, 40000, 86,0 }, + {3610,3610, 0, 0, 820, 206,0 }, + {3611,3611, 0, 0, 40000, 66,0 }, + {3612,3612, 0, 0, 40000, 200,0 }, + {3613,3613, 0, 0, 18186, 720,0 }, + {3614,3614, 0, 0, 40000, 0,0 }, + {3615,3615, 0, 0, 40000, 493,0 }, + {3616,3616, 0, 0, 40000, 306,0 }, + {3617,3617, 0, 0, 2166, 600,0 }, + {3618,3618, 0, 0, 40000, 73,0 }, + {3619,3619, 0, 0, 40000, 3073,0 }, + {3620,3620, 0, 0, 2333, 413,0 }, + {3621,3621, 0, 0, 14880, 73,0 }, + {3622,3622, 0, 0, 40000, 66,0 }, + {3623,3623, 0, 0, 40000, 73,0 }, + {3624,3624, 0, 0, 40000, 1873,0 }, + {3625,3625, 0, 0, 40000, 446,0 }, + {3626,3626, 0, 0, 40000, 3126,0 }, + {3627,3627, 0, 0, 18446, 6140,0 }, + {3628,3628, 0, 0, 1113, 240,0 }, + {3629,3629, 0, 0, 40000, 3600,0 }, + {3630,3630, 0, 0, 40000, 4726,0 }, + {3631,3631, 0, 0, 40000, 0,0 }, + {3632,3632, 0, 0, 2893, 606,0 }, + {3633,3633, 0, 0, 40000, 0,0 }, + {3634,3634, 0, 0, 40000, 0,0 }, + {3635,3635, 0, 0, 40000, 173,0 }, + {3636,3636, 0, 0, 40000, 60,0 }, + {3637,3637, 0, 0, 40000, 0,0 }, + {3638,3638, 0, 0, 986, 326,0 }, + {3639,3639, 0, 0, 1873, 646,0 }, + {3640,3640, 0, 0, 200, 260,0 }, + {3641,3641, 0, 0, 1180, 393,0 }, + {3642,3642, 0, 0, 266, 0,0 }, + {3643,3643, 0, 0, 313, 126,0 }, + {3644,3644, 0, 0, 406, 253,0 }, + {3645,3645, 0, 0, 1013, 813,0 }, + {3646,3646, 0, 0, 273, 53,0 }, + {3647,3647, 0, 0, 720, 213,0 }, + {3648,3648, 0, 0, 386, 120,0 }, + {3649,3649, 0, 0, 40000, 766,0 }, + {3650,3650, 0, 0, 40000, 66,0 }, + {3651,3651, 0, 0, 40000, 73,0 }, + {3652,3652, 0, 0, 1186, 426,0 }, + {3653,3653, 0, 0, 16720, 240,0 }, + {3654,3654, 0, 0, 8026, 246,0 }, + {3655,3655, 0, 0, 18186, 140,0 }, + {3656,3656, 0, 0, 14566, 200,0 }, + {3657,3657, 0, 0, 7973, 20,0 }, + {3658,3658, 0, 0, 4446, 86,0 }, + {3659,3659, 0, 0, 4473, 100,0 }, + {3660,3660, 0, 0, 8646, 153,0 }, + {3661,3661, 0, 0, 3726, 660,0 }, + {3662,3662, 0, 0, 1893, 653,0 }, + {3663,3663, 0, 0, 1933, 760,0 }, + {3664,3664, 0, 0, 9160, 240,0 }, + {3665,3665, 0, 0, 1133, 100,0 }, + {3666,3666, 0, 0, 633, 233,0 }, + {3667,3667, 0, 0, 9153, 3060,0 }, + {3668,3668, 0, 0, 2166, 406,0 }, + {3669,3669, 0, 0, 40000, 66,0 }, + {3670,3670, 0, 0, 40000, 73,0 }, + {3671,3671, 0, 0, 40000, 73,0 }, + {3672,3672, 0, 0, 40000, 73,0 }, + {3673,3673, 0, 0, 40000, 346,0 }, + {3674,3674, 0, 0, 40000, 353,0 }, + {3675,3675, 0, 0, 40000, 200,0 }, + {3676,3676, 0, 0, 40000, 320,0 }, + {3677,3677, 0, 0, 4646, 100,0 }, + {3678,3678, 0, 0, 4426, 133,0 }, + {3679,3679, 0, 0, 4633, 100,0 }, + {3680,3680, 0, 0, 2266, 133,0 }, + {3681,3681, 0, 0, 2346, 53,0 }, + {3682,3682, 0, 0, 40000, 66,0 }, + {3683,3683, 0, 0, 9686, 173,0 }, + {3684,3684, 0, 0, 14300, 66,0 }, + {3685,3685, 0, 0, 40000, 0,0 }, + {3686,3686, 0, 0, 40000, 0,0 }, + {3687,3687, 0, 0, 40000, 0,0 }, + {3688,3688, 0, 0, 8613, 73,0 }, + {3689,3689, 0, 0, 40000, 0,0 }, + {3690,3690, 0, 0, 40000, 0,0 }, + {3691,3691, 0, 0, 40000, 0,0 }, + {3692,3692, 0, 0, 40000, 0,0 }, + {3693,3693, 0, 0, 40000, 393,0 }, + {3694,3694, 0, 0, 40000, 126,0 }, + {3695,3695, 0, 0, 40000, 120,0 }, + {3696,3696, 0, 0, 40000, 0,0 }, + {3697,3697, 0, 0, 40000, 226,0 }, + {3698,3698, 0, 0, 7420, 1186,0 }, + {3699,3699, 0, 0, 3280, 1726,0 }, + {3700,3700, 0, 0, 3680, 1220,0 }, + {3701,3701, 0, 0, 40000, 480,0 }, + {3702,3702, 0, 0, 40000, 306,0 }, + {3703,3703, 0, 0, 40000, 433,0 }, + {3704,3704, 0, 0, 40000, 133,0 }, + {3705,3705, 0, 0, 40000, 0,0 }, + {3706,3706, 0, 0, 40000, 0,0 }, + {3707,3707, 0, 0, 1166, 380,0 }, + {3708,3708, 0, 0, 40000, 140,0 }, + {3709,3709, 0, 0, 40000, 126,0 }, + {3710,3710, 0, 0, 40000, 100,0 }, + {3711,3711, 0, 0, 40000, 66,0 }, + {3712,3712, 0, 0, 40000, 226,0 }, + {3713,3713, 0, 0, 40000, 133,0 }, + {3714,3714, 0, 0, 40000, 73,0 }, + {3715,3715, 0, 0, 40000, 226,0 }, + {3716,3716, 0, 0, 40000, 100,0 }, + {3717,3717, 0, 0, 40000, 80,0 }, + {3718,3718, 0, 0, 40000, 100,0 }, + {3719,3719, 0, 0, 40000, 73,0 }, + {3720,3720, 0, 0, 40000, 73,0 }, + {3721,3721, 0, 0, 40000, 73,0 }, + {3722,3722, 0, 0, 40000, 126,0 }, + {3723,3723, 0, 0, 40000, 80,0 }, + {3724,3724, 0, 0, 40000, 73,0 }, + {3725,3725, 0, 0, 40000, 86,0 }, + {3726,3726, 0, 0, 40000, 100,0 }, + {3727,3727, 0, 0, 40000, 0,0 }, + {3728,3728, 0, 0, 40000, 126,0 }, + {3729,3729, 0, 0, 40000, 133,0 }, + {3730,3730, 0, 0, 40000, 140,0 }, + {3731,3731, 0, 0, 40000, 73,0 }, + {3732,3732, 0, 0, 40000, 60,0 }, + {3733,3733, 0, 0, 40000, 93,0 }, + {3734,3734, 0, 0, 40000, 80,0 }, + {3735,3735, 0, 0, 40000, 66,0 }, + {3736,3736, 0, 0, 40000, 0,0 }, + {3737,3737, 0, 0, 40000, 220,0 }, + {3738,3738, 0, 0, 40000, 80,0 }, + {3739,3739, 0, 0, 40000, 400,0 }, + {3740,3740, 0, 0, 40000, 1373,0 }, + {3741,3741, 0, 0, 40000, 86,0 }, + {3742,3742, 0, 0, 40000, 1313,0 }, + {3743,3743, 0, 0, 40000, 0,0 }, + {3744,3744, 0, 0, 11486, 593,0 }, + {3745,3745, 0, 0, 40000, 1246,0 }, + {3746,3746, 0, 0, 40000, 140,0 }, + {3747,3747, 0, 0, 14386, 2680,0 }, + {3748,3748, 0, 0, 40000, 653,0 }, + {3749,3749, 0, 0, 2286, 713,0 }, + {3750,3750, 0, 0, 40000, 253,0 }, + {3751,3751, 0, 0, 6933, 406,0 }, + {3752,3752, 0, 0, 40000, 1313,0 }, + {3753,3753, 0, 0, 40000, 1440,0 }, + {3754,3754, 0, 0, 40000, 73,0 }, + {3755,3755, 0, 0, 11100, 420,0 }, + {3756,3756, 0, 0, 6493, 320,0 }, + {3757,3757, 0, 0, 3486, 126,0 }, + {3758,3758, 0, 0, 6620, 2133,0 }, + {3759,3759, 0, 0, 1180, 413,0 }, + {3760,3760, 0, 0, 40000, 73,0 }, + {3761,3761, 0, 0, 40000, 73,0 }, + {3762,3762, 0, 0, 40000, 66,0 }, + {3763,3763, 0, 0, 4580, 413,0 }, + {3764,3764, 0, 0, 340, 146,0 }, + {3765,3765, 0, 0, 1166, 400,0 }, + {3766,3766, 0, 0, 1346, 660,0 }, + {3767,3767, 0, 0, 1260, 393,0 }, + {3768,3768, 0, 0, 3646, 1186,0 }, + {3769,3769, 0, 0, 2713, 400,0 }, + {3770,3770, 0, 0, 1780, 73,0 }, + {3771,3771, 0, 0, 800, 213,0 }, + {3772,3772, 0, 0, 660, 173,0 }, + {3773,3773, 0, 0, 12146, 73,0 }, + {3774,3774, 0, 0, 273, 60,0 }, + {3775,3775, 0, 0, 40000, 73,0 }, + {3776,3776, 0, 0, 380, 53,0 }, + {3777,3777, 0, 0, 40000, 200,0 }, + {3778,3778, 0, 0, 586, 20,0 }, + {3779,3779, 0, 2, 6, 0,0 }, + { 738, 738, 44, 0, 840, 340,0 }, + {3780,3780, 36, 0, 7366, 140,0 }, + {3781,3781, 32, 0, 100, 0,0 }, + {2030,2030, 60, 0, 293, 126,0 }, + {3782,3782, 24, 0, 100, 0,0 }, + {3783,3783, 60, 0, 126, 73,0 }, + {3784,3784, 44, 0, 393, 93,0 }, + { 132, 132, 44, 0, 173, 100,0 }, + {3785,3785, 47, 0, 393, 93,0 }, + { 152, 152, 44, 0, 213, 86,0 }, + {3784,3784, 50, 0, 393, 93,0 }, + { 139, 139, 44, 0, 293, 100,0 }, + {3784,3784, 54, 0, 393, 93,0 }, + {3784,3784, 57, 0, 393, 93,0 }, + {3786,3786, 60, 0, 1900, 666,0 }, + {3784,3784, 60, 0, 393, 93,0 }, + {3787,3787, 60, 0, 1900, 666,0 }, + {3788,3788, 60, 0, 1886, 666,0 }, + {3789,3789, 60, 0, 1866, 653,0 }, + {3790,3790, 60, 0, 1873, 633,0 }, + {3791,3791, 44, 0, 946, 333,0 }, + {2037,2037, 44, 0, 213, 126,0 }, + { 144, 144, 44, 0, 213, 126,0 }, + {2038,2038, 44, 0, 106, 0,0 }, + {3792,3792, 44, 0, 380, 360,0 }, + {3793,3793, 44, 0, 520, 206,0 }, + {3794,3794, 45, 0, 273, 100,0 }, + {3795,3795, 33, 0, 326, 106,0 }, + {3796,3796, 56, 0, 506, 200,0 }, + {3796,3796, 51, 0, 506, 200,0 }, + {3797,3797, 44, 0, 126, 66,0 }, + {3798,3798, 44, 0, 553, 186,0 }, + {3534,3534, 56, 0, 240, 100,0 }, + { 158, 158, 68, 0, 126, 140,0 }, + {3799,3799, 51, 0, 513, 206,0 }, + {3800,3800, 46, 0, 506, 200,0 }, + {3801,3801, 44, 0, 513, 206,0 }, + {3802,3802, 44, 0, 3720, 1260,0 }, + { 152, 152, 45, 0, 220, 80,0 }, + {3803,3803, 0, 0, 40000, 86,0 }, + {3804,3804, 0, 0, 40000, 226,0 }, + {3805,3805, 0, 0, 40000, 73,0 }, + {3806,3806, 0, 0, 40000, 73,0 }, + {3807,3807, 0, 0, 40000, 93,0 }, + {3808,3808, 0, 0, 4653, 660,0 }, + {3809,3809, 0, 0, 6686, 2246,0 }, + {3810,3810, 0, 0, 1180, 413,0 }, + {3811,3811, 0, 0, 966, 293,0 }, + {3812,3812, 0, 0, 1780, 66,0 }, + {3780,3780, 45, 0, 5900, 113,0 }, + {3061,3061, 45, 0, 40000, 0,0 }, + {3813,3813, 60, 0, 126, 226,0 }, + {3781,3781, 60, 0, 93, 0,0 }, + {3814,3814, 44, 0, 393, 86,0 }, + {3815,3815, 57, 0, 166, 80,0 }, + {3816,3816, 56, 0, 240, 100,0 }, + {3817,3817, 60, 0, 113, 0,0 }, + {3818,3818, 60, 0, 113, 0,0 }, + {3517,3517, 45, 0, 213, 213,0 }, + {3819,3819, 0, 0, 4033, 100,0 }, + {3820,3820, 0, 0, 5200, 873,0 }, + {3821,3821, 0, 0, 40000, 0,0 }, + {3822,3822, 0, 0, 10493, 160,0 }, + {3823,3823, 0, 0, 40000, 740,0 }, + {3824,3825, 0, 1, 40000, 366,0.078125 }, + {3826,3826, 0, 0, 40000, 5100,0 }, + {3827,3827, 0, 0, 40000, 766,0 }, + {3828,1172, 0, 1, 40000, 780,0.15625 }, + {3829,3829, 0, 0, 40000, 60,0 }, + {3830,3830, 0, 0, 566, 133,0 }, + {3831,3831, 32, 0, 146, 0,0 }, + {3832,3832, 36, 0, 273, 0,0 }, + {3833,3833, 88, 0, 340, 120,0 }, + {3834,3834, 0, 0, 9006, 240,0 }, + {3835,3835, 0, 0, 9206, 246,0 }, + {3836,3836, 0, 0, 9246, 386,0 }, + {3837,3837, 0, 0, 9440, 220,0 }, + {3838,3838, 0, 0, 8900, 133,0 }, + {3839,3839, 0, 0, 9400, 253,0 }, + {3840,3840, 0, 0, 4613, 420,0 }, + {3841,3841, 0, 0, 9233, 426,0 }, + {3842,3842, 0, 0, 40000, 526,0 }, + {3843,3843, 0, 0, 40000, 640,0 }, + {3844,3844, 0, 0, 40000, 666,0 }, + {3845,3845, 0, 0, 40000, 1053,0 }, + {3846,3846, 0, 0, 40000, 173,0 }, + {3847,3847, 0, 0, 40000, 246,0 }, + {3848,3848, 0, 0, 40000, 226,0 }, + {3849,3849, 0, 0, 4073, 233,0 }, + {3850,3850, 0, 0, 14286, 326,0 }, + {3851,3851, 0, 0, 9233, 146,0 }, + {3852,3852, 0, 0, 4480, 133,0 }, + {3853,3853, 0, 0, 40000, 53,0 }, + {3854,3854, 0, 0, 40000, 126,0 }, + {3855,3855, 0, 0, 40000, 126,0 }, + {3856,3856, 0, 0, 18226, 146,0 }, + {3857,3857, 0, 0, 40000, 326,0 }, + {3858,3858, 0, 0, 40000, 0,0 }, + {3859,3859, 0, 0, 40000, 300,0 }, + {3860,3860, 0, 0, 40000, 0,0 }, + {3861,3861, 0, 0, 40000, 0,0 }, + {3862,3862, 0, 0, 40000, 0,0 }, + {3863,3863, 0, 0, 40000, 140,0 }, + {3864,3864, 0, 0, 40000, 153,0 }, + {3865,3865, 0, 0, 40000, 233,0 }, + {3866,3866, 0, 0, 40000, 186,0 }, + {3867,3867, 0, 0, 40000, 413,0 }, + {3868,3868, 0, 0, 40000, 373,0 }, + {3869,3869, 0, 0, 1246, 440,0 }, + {3870,3870, 0, 0, 4620, 1513,0 }, + {3871,3871, 0, 0, 40000, 433,0 }, + {3872,3872, 0, 0, 40000, 453,0 }, + {3873,3873, 0, 0, 40000, 1440,0 }, + {3874,3874, 0, 0, 40000, 480,0 }, + {3875,3875, 0, 0, 40000, 1360,0 }, + {3876,3876, 0, 0, 40000, 0,0 }, + {3877,3877, 0, 0, 40000, 353,0 }, + {3878,3878, 0, 0, 40000, 86,0 }, + {3879,3879, 0, 0, 40000, 126,0 }, + {3880,3880, 0, 0, 40000, 73,0 }, + {3881,3881, 0, 0, 40000, 80,0 }, + {3882,3882, 0, 0, 40000, 246,0 }, + {3883,3883, 0, 0, 40000, 93,0 }, + {3884,3884, 0, 0, 40000, 120,0 }, + {3885,3885, 0, 0, 40000, 180,0 }, + {3886,3886, 0, 0, 40000, 133,0 }, + {3887,3887, 0, 0, 40000, 133,0 }, + {3888,3888, 0, 0, 40000, 153,0 }, + {3889,3889, 0, 0, 40000, 93,0 }, + {3890,3890, 0, 0, 40000, 140,0 }, + {3891,3891, 0, 0, 40000, 100,0 }, + {3892,3892, 0, 0, 40000, 146,0 }, + {3893,3893, 0, 0, 40000, 126,0 }, + {3894,3894, 0, 0, 40000, 160,0 }, + {3895,3895, 0, 0, 40000, 226,0 }, + {3896,3896, 0, 0, 40000, 140,0 }, + {3897,3897, 0, 0, 40000, 200,0 }, + {3898,3898, 0, 0, 40000, 66,0 }, + {3899,3899, 0, 0, 40000, 446,0 }, + {3900,3900, 0, 0, 40000, 140,0 }, + {3901,3901, 0, 0, 40000, 400,0 }, + {3902,3902, 0, 0, 40000, 373,0 }, + {3903,3903, 0, 0, 40000, 1306,0 }, + {3904,3904, 0, 0, 40000, 186,0 }, + {3905,3905, 0, 0, 40000, 640,0 }, + {3906,3906, 0, 0, 40000, 346,0 }, + {3907,3907, 0, 0, 40000, 140,0 }, + {3908,3908, 0, 0, 40000, 253,0 }, + {3909,3909, 0, 0, 8980, 746,0 }, + {3910,3910, 0, 0, 40000, 1266,0 }, + {3911,3911, 0, 0, 40000, 1306,0 }, + {3912,3912, 0, 0, 7226, 593,0 }, + {3913,3913, 0, 0, 40000, 140,0 }, + {3914,3914, 0, 0, 40000, 220,0 }, + {3915,3915, 0, 0, 40000, 146,0 }, + {3916,3916, 0, 0, 4606, 1506,0 }, + {3917,3917, 0, 0, 40000, 80,0 }, + {3918,3918, 0, 0, 40000, 0,0 }, + {3919,3919, 0, 0, 40000, 0,0 }, + {3920,3920, 0, 0, 613, 226,0 }, + {3921,3921, 0, 0, 9073, 2946,0 }, + {3922,3922, 0, 0, 40000, 73,0 }, + {3923,3923, 0, 0, 3726, 200,0 }, + {3924,3924, 0, 0, 3680, 373,0 }, + {3925,3925, 0, 0, 7113, 186,0 }, + {3926,3926, 0, 0, 2406, 106,0 }, + {3927,3927, 0, 0, 40000, 0,0 }, + {3928,3928, 0, 0, 40000, 253,0 }, + {3929,3929, 0, 0, 40000, 0,0 }, + {3930,3930, 0, 0, 40000, 80,0 }, + {3931,3931, 0, 0, 40000, 86,0 }, + {3932,3932, 0, 0, 18186, 740,0 }, + {3933,3933, 0, 0, 18426, 813,0 }, + { 523, 523, 0, 0, 200, 260,0 }, + {3934,3934, 0, 0, 340, 146,0 }, + {3935,3935, 0, 0, 366, 260,0 }, + {3936,3936, 48, 0, 126, 0,0 }, + {3937,3937, 27, 0, 200, 106,0 }, + {3938,3938, 40, 0, 1073, 800,0 }, + {3939,3939, 48, 0, 100, 0,0 }, + {3938,3938, 45, 0, 933, 666,0 }, + {3940,3940, 48, 0, 140, 333,0 }, + {3938,3938, 47, 0, 933, 666,0 }, + {3941,3941, 48, 0, 1840, 0,0 }, + {3938,3938, 49, 0, 953, 686,0 }, + {3938,3938, 53, 0, 906, 686,0 }, + {3938,3938, 56, 0, 913, 693,0 }, + { 129, 129, 52, 0, 293, 126,0 }, + { 130, 130, 48, 0, 173, 93,0 }, + { 129, 129, 58, 0, 286, 126,0 }, + { 132, 132, 47, 0, 173, 100,0 }, + { 492, 492, 43, 0, 820, 306,0 }, + { 132, 132, 49, 0, 173, 93,0 }, + { 132, 132, 51, 0, 173, 93,0 }, + { 132, 132, 54, 0, 173, 93,0 }, + { 132, 132, 57, 0, 146, 86,0 }, + { 492, 492, 72, 0, 706, 300,0 }, + { 137, 137, 76, 0, 1900, 666,0 }, + { 138, 138, 84, 0, 740, 300,0 }, + { 139, 139, 36, 0, 353, 146,0 }, + { 140, 140, 76, 0, 1886, 680,0 }, + { 141, 141, 84, 0, 220, 113,0 }, + { 135, 135, 83, 0, 1353, 480,0 }, + { 142, 142, 84, 0, 386, 160,0 }, + {3942,3942, 24, 0, 2313, 780,0 }, + { 137, 137, 77, 0, 1893, 660,0 }, + { 144, 144, 60, 0, 213, 0,0 }, + { 145, 145, 65, 0, 180, 146,0 }, + { 146, 146, 59, 0, 173, 93,0 }, + { 147, 147, 51, 0, 266, 213,0 }, + { 148, 148, 45, 0, 513, 200,0 }, + { 149, 149, 71, 0, 246, 26,0 }, + { 150, 150, 60, 0, 500, 193,0 }, + { 151, 151, 58, 0, 513, 200,0 }, + { 152, 152, 53, 0, 220, 86,0 }, + { 153, 153, 64, 0, 113, 40,0 }, + { 154, 154, 71, 0, 840, 300,0 }, + { 156, 156, 61, 0, 166, 80,0 }, + { 158, 158, 48, 0, 173, 213,0 }, + { 159, 159, 69, 0, 126, 140,0 }, + { 160, 160, 68, 0, 126, 140,0 }, + { 161, 161, 63, 0, 326, 113,0 }, + { 162, 162, 74, 0, 860, 286,0 }, + { 163, 163, 60, 0, 386, 160,0 }, + { 164, 164, 80, 0, 1106, 273,0 }, + { 165, 165, 64, 0, 126, 66,0 }, + { 166, 166, 69, 0, 386, 80,0 }, + { 167, 167, 73, 0, 546, 306,0 }, + { 168, 168, 75, 0, 126, 140,0 }, + { 169, 169, 68, 0, 340, 320,0 }, + { 131, 131, 48, 0, 520, 200,0 }, + {3061,3061, 53, 0, 40000, 0,0 }, + {3943,3944, 0, 4, 2153, 0,0 }, + {3945,3946, 0, 4, 9060, 393,0 }, + { 174,3947, 0, 4, 6953, 0,0 }, + {3948,3949, 0, 4, 9386, 140,0 }, + { 9,3950, 0, 4, 1626, 426,0 }, + {3951,3952, 0, 4, 18466, 240,0 }, + {3953,3954, 0, 4, 4666, 1486,0 }, + { 15,3955, 0, 4, 5700, 1986,0 }, + {3956,3957, 0, 4, 40000, 100,0 }, + {3958,3959, 0, 4, 40000, 73,0 }, + {3960,3961, 0, 4, 40000, 73,0 }, + {3962,3963, 0, 4, 40000, 73,0 }, + {3964,3965, 0, 4, 18280, 153,0 }, + {3966,3965, 0, 4, 18686, 160,0 }, + { 31,3967, 0, 4, 40000, 0,0 }, + {3968,3969, 0, 4, 17966, 100,0 }, + {3970,3971, 0, 4, 40000, 66,0 }, + {3972,3971, 0, 4, 40000, 66,0 }, + {3973,3974, 0, 4, 40000, 46,0 }, + {3975,3976, 0, 4, 18693, 106,0 }, + {3977,3976, 0, 4, 18593, 106,0 }, + {3978,3979, 0, 4, 9366, 106,0 }, + {3980,3981, 0, 4, 9120, 226,0 }, + {3982,3983, 0, 4, 40000, 140,0 }, + {3984,3985, 0, 4, 40000, 800,0 }, + { 54,3986, 0, 4, 2520, 706,0 }, + {3987,3988, 0, 4, 40000, 86,0 }, + {3989,3990, 0, 4, 40000, 233,0 }, + {3991, 253, 0, 4, 40000, 66,0 }, + {3992,3992, 0, 0, 40000, 0,0 }, + {3993,3993, 0, 0, 40000, 120,0 }, + {3994,3995, 0, 4, 40000, 80,0 }, + {3996,3997, 0, 4, 40000, 73,0 }, + {3998,3999, 0, 4, 40000, 86,0 }, + {1503,4000, 0, 4, 40000, 93,0 }, + { 88,4001, 0, 4, 40000, 1220,0 }, + {3743,4002, 0, 4, 7706, 1260,0 }, + { 92,4003, 0, 4, 40000, 186,0 }, + { 93,4004, 0, 4, 40000, 813,0 }, + { 94,4005, 0, 4, 7720, 1260,0 }, + { 96,4006, 0, 4, 40000, 2460,0 }, + { 103,4007, 0, 4, 3720, 1240,0 }, + { 104,4008, 0, 4, 3020, 1226,0 }, + { 105,4009, 0, 4, 6086, 2453,0 }, + { 107,4010, 0, 4, 2100, 760,0 }, + { 108,4011, 0, 4, 40000, 73,0 }, + { 110,4012, 0, 4, 40000, 100,0 }, + { 111,4013, 0, 4, 2366, 820,0 }, + {4014,4015, 0, 4, 1026, 326,0 }, + { 115,4016, 0, 4, 1853, 0,0 }, + { 118,4017, 0, 4, 1553, 53,0 }, + { 119,4018, 0, 4, 593, 0,0 }, + { 120,4019, 0, 4, 2293, 1173,0 }, + { 121,4020, 0, 4, 10673, 3000,0 }, + { 123,4021, 0, 4, 7413, 2486,0 }, + { 124,4022, 0, 4, 40000, 1126,0 }, + { 125,4023, 0, 4, 40000, 1546,0 }, + {4024,4024, 35, 0, 706, 266,0 }, + {4025,4026, 38, 1, 273, 106,0 }, + {4027,4028, 38, 1, 366, 133,0 }, + {4029,4030, 48, 1, 280, 133,-1.90625 }, + {4031,4031, 51, 0, 113, 80,0 }, + {4032,4033, 48, 1, 953, 346,-1.90625 }, + {4034,4034, 61, 1, 3200, 540,0.09375 }, + {3369,1557, 70, 4, 833, 0,0 }, + {4035,4036, 79, 1, 1306, 513,0.078125 }, + {4037,4037, 62, 0, 5200, 466,0 }, + {4038,4039, 67, 1, 2153, 1080,0.078125 }, + {4040,4040, 62, 1, 3226, 573,0.09375 }, + {4041,4042, 54, 1, 286, 133,0 }, + {4041,4043, 48, 1, 286, 126,0 }, + { 389, 389, 42, 0, 266, 73,0 }, + {4044,4045, 48, 1, 280, 126,0 }, + {4046,4047, 48, 1, 380, 60,0 }, + {4048,4048, 16, 0, 180, 20,0 }, + {4049,4049, 16, 0, 740, 20,0 }, + {4050,4051, 64, 4, 1366, 0,0 }, + { 844, 844,244, 2, 6, 0,0 }, + { 855, 855,244, 2, 6, 0,0 }, + { 880, 880,232, 0, 253, 80,0 }, + { 882, 882,220, 0, 40000, 266,0 }, + { 887, 887, 35, 0, 133, 46,0 }, + { 884, 884, 35, 0, 233, 80,0 }, + { 885, 885, 35, 0, 226, 86,0 }, + { 886, 886, 35, 0, 113, 0,0 }, + { 361, 361, 35, 0, 286, 73,0 }, + { 767, 767, 35, 0, 3020, 786,0 }, + { 888, 888, 35, 0, 246, 53,0 }, + {2141,2141, 35, 0, 186, 73,0 }, + { 891, 891, 35, 0, 713, 266,0 }, + {2142,2142, 35, 0, 200, 100,0 }, + {2143,2143, 35, 0, 220, 80,0 }, + {2144,2144, 35, 0, 2393, 100,0 }, + {2145,2145, 35, 0, 1980, 813,0 }, + { 376, 376, 35, 0, 1880, 840,0 }, + { 895, 895, 35, 0, 366, 140,0 }, + {2146,2146, 35, 0, 346, 106,0 }, + { 382, 382, 35, 0, 1073, 113,0 }, + {2147,2147, 35, 0, 106, 80,0 }, + { 898, 898, 35, 0, 206, 153,0 }, + { 899, 899, 35, 0, 633, 240,0 }, + { 900, 900, 35, 0, 620, 240,0 }, + { 871, 871, 35, 0, 380, 73,0 }, + { 388, 388, 35, 0, 286, 80,0 }, + { 901, 901, 35, 0, 260, 26,0 }, + { 902, 902, 35, 0, 1093, 73,0 }, + { 903, 903, 35, 0, 126, 73,0 }, + {3500,3500, 35, 2, 6, 0,0 }, + {4052,4052, 0, 0, 14166, 320,0 }, + {4053,4053, 0, 0, 7413, 653,0 }, + {4054,4054, 0, 0, 40000, 146,0 }, + {4055,4055, 0, 0, 40000, 113,0 }, + {4056,4056, 0, 0, 16773, 193,0 }, + {4057,4057, 0, 0, 40000, 73,0 }, + {4058,4058, 0, 0, 40000, 0,0 }, + {4059,4059, 0, 0, 966, 373,0 }, + {4060,4060, 0, 0, 40000, 80,0 }, + {4061,4061, 0, 0, 40000, 80,0 }, + {4062,4062, 0, 0, 18473, 93,0 }, + {4063,4063, 0, 0, 40000, 60,0 }, + {4064,4064, 0, 0, 40000, 73,0 }, + {4065,4065, 0, 0, 40000, 0,0 }, + {4066,4066, 0, 0, 40000, 213,0 }, + {4067,4067, 0, 0, 40000, 66,0 }, + {4068,4068, 0, 0, 1413, 1026,0 }, + {4069,4069, 0, 0, 506, 200,0 }, + {4070,4070, 0, 0, 3793, 1106,0 }, + {4071,4071, 0, 0, 40000, 220,0 }, + {4072,4072, 0, 0, 40000, 46,0 }, + {4073,4073, 0, 0, 40000, 0,0 }, + {4074,4074, 0, 0, 40000, 60,0 }, + {4075,4075, 0, 0, 40000, 0,0 }, + {4076,4076, 0, 0, 40000, 33,0 }, + {4077,4077, 0, 0, 40000, 0,0 }, + {4078,4078, 0, 0, 40000, 146,0 }, + {4079,4079, 0, 0, 40000, 66,0 }, + {4080,4080, 0, 0, 40000, 353,0 }, + {4081,4081, 0, 0, 40000, 66,0 }, + {4082,4082, 0, 0, 40000, 53,0 }, + {4083,4083, 0, 0, 40000, 73,0 }, + {4084,4084, 0, 0, 40000, 66,0 }, + {4085,4085, 0, 0, 40000, 926,0 }, + {4086,4086, 0, 0, 2833, 200,0 }, + { 127, 127, 36, 0, 386, 166,0 }, + {4087,4087, 36, 0, 100, 0,0 }, + {2030,2030, 36, 0, 346, 140,0 }, + {3782,3782, 48, 0, 93, 0,0 }, + {3783,3783, 36, 0, 146, 0,0 }, + {4088,4088, 48, 0, 1886, 653,0 }, + { 132, 132, 69, 0, 126, 66,0 }, + {4088,4088, 52, 0, 1853, 626,0 }, + { 152, 152, 48, 0, 220, 86,0 }, + {4088,4088, 55, 0, 1886, 640,0 }, + { 139, 139, 57, 0, 293, 133,0 }, + {4088,4088, 58, 0, 1860, 633,0 }, + {4088,4088, 60, 0, 1886, 633,0 }, + {4089,4089, 62, 0, 2660, 900,0 }, + {4088,4088, 63, 0, 1880, 646,0 }, + { 134, 134, 70, 0, 966, 360,0 }, + {4090,4090, 70, 0, 973, 346,0 }, + {4091,4091, 53, 0, 1866, 640,0 }, + {3516,3516, 48, 0, 180, 93,0 }, + {4092,4092, 84, 0, 1360, 473,0 }, + {4093,4093, 43, 0, 513, 206,0 }, + {4094,4094, 56, 0, 1353, 480,0 }, + {3791,3791, 24, 0, 1866, 613,0 }, + { 134, 134, 65, 0, 1346, 486,0 }, + { 146, 146, 48, 0, 173, 93,0 }, + { 146, 146, 54, 0, 173, 93,0 }, + {4095,4095, 42, 0, 246, 140,0 }, + {4095,4095, 39, 0, 240, 133,0 }, + {3816,3816, 52, 0, 306, 113,0 }, + {4096,4096, 52, 0, 413, 86,0 }, + { 158, 158, 60, 0, 146, 166,0 }, + { 158, 158, 66, 0, 146, 166,0 }, + { 158, 158, 59, 0, 146, 166,0 }, + {3538,3538, 91, 0, 773, 233,0 }, + {3547,3547,109, 0, 5300, 1786,0 }, + {4097,4097, 79, 0, 560, 313,0 }, + {4098,4098, 0, 0, 10646, 73,0 }, + {4099,4100, 0, 1, 14166, 586,0.03125 }, + {4101,4102, 0, 1, 15553, 546,0.03125 }, + {4103,4104, 0, 1, 11746, 320,0.046875 }, + {4105,4106, 0, 1, 14706, 646,0.15625 }, + {4107,4108, 0, 1, 7320, 100,0.046875 }, + {4109,4110, 0, 1, 40000, 0,0.0625 }, + {4111,4112, 0, 1, 13660, 260,0 }, + {4113,4114, 0, 1, 15026, 133,0 }, + {4115,4116, 0, 1, 40000, 0,2.5e-05 }, + {4117,4118, 0, 1, 4980, 3400,0 }, + {4119,4120, 0, 1, 7840, 2660,0.046875 }, + {4121,4122, 0, 1, 8326, 180,0 }, + {4123,4124, 0, 1, 1093, 140,0 }, + {4125,4126, 0, 1, 2280, 400,0 }, + {4127,4128, 0, 1, 4553, 1486,0.03125 }, + {4129,4129, 0, 1, 40000, 0,0.03125 }, + {4130,4131, 0, 1, 40000, 60,0.15625 }, + {4132,4133, 0, 1, 40000, 93,0.078125 }, + {4134,4135, 0, 1, 40000, 86,0.15625 }, + {4136,4137, 0, 1, 40000, 520,0.03125 }, + {4138,4139, 0, 1, 40000, 140,0.0625 }, + {4140,4141, 0, 1, 40000, 133,0.140625 }, + {4142,4143, 0, 1, 40000, 73,0 }, + {4144,4145, 0, 1, 40000, 346,0.109375 }, + {4146,4147, 0, 1, 3693, 86,0 }, + {4148,4149, 0, 1, 6586, 460,2.5e-05 }, + {4150,4151, 0, 1, 4320, 93,0 }, + {4152,4153, 0, 1, 7346, 126,0.046875 }, + {4154,4155, 0, 1, 3633, 260,0 }, + {4156,4157, 0, 1, 40000, 126,-1.95312 }, + {4158,4159, 0, 1, 40000, 126,-1.9375 }, + {4160,4161, 0, 1, 40000, 46,0.234375 }, + {4162,4163, 0, 1, 40000, 0,0.03125 }, + {4164,4165, 0, 1, 10320, 86,0 }, + {4166,4167, 0, 1, 12933, 133,0 }, + {4168,4169, 0, 1, 11820, 240,0.046875 }, + {4170,4171, 0, 1, 3966, 166,0 }, + {4172,4173, 0, 1, 40000, 0,0 }, + {4174,4174, 0, 0, 2666, 160,0 }, + {4175,4176, 0, 1, 15046, 93,0.078125 }, + {4177,4178, 0, 1, 40000, 100,0 }, + {4179,4179, 0, 0, 40000, 260,0 }, + {4180,4181, 0, 1, 40000, 126,2.5e-05 }, + {4182,4182, 0, 0, 40000, 233,0 }, + {4183,4184, 0, 1, 40000, 440,0.078125 }, + {4185,4186, 0, 1, 2160, 606,0.109375 }, + {4187,4188, 0, 1, 14753, 2400,0.03125 }, + {4189,4190, 0, 1, 7693, 0,0.03125 }, + {4191,4192, 0, 1, 40000, 446,0.0625 }, + {4193,4194, 0, 1, 40000, 866,-0.0625 }, + {4195,4195, 0, 1, 40000, 1226,0.109375 }, + {4196,4196, 0, 1, 40000, 1960,0.109375 }, + {4197,4198, 0, 1, 40000, 433,0.125 }, + {4199,4200, 0, 1, 40000, 140,0.140625 }, + {4201,4202, 0, 1, 40000, 706,0.15625 }, + {4203,4204, 0, 1, 1640, 0,0.125 }, + {4205,4206, 0, 1, 40000, 86,0 }, + {4207,4208, 0, 1, 40000, 80,0.03125 }, + {4209,4209, 0, 0, 40000, 73,0 }, + {4210,4210, 0, 0, 40000, 126,0 }, + {4211,4212, 0, 1, 40000, 353,0.03125 }, + {4213,4214, 0, 1, 40000, 120,0.0625 }, + {4215,4216, 0, 1, 40000, 0,0.09375 }, + {4217,4217, 0, 1, 40000, 0,0.125 }, + {4218,4219, 0, 1, 40000, 186,0 }, + {4220,4220, 0, 0, 40000, 166,0 }, + {4221,4221, 0, 0, 40000, 73,0 }, + {4222,4222, 0, 0, 40000, 60,0 }, + {4223,4224, 0, 1, 40000, 140,0 }, + {4225,4225, 0, 0, 40000, 140,0 }, + {4226,4226, 0, 0, 40000, 66,0 }, + {4227,4228, 0, 1, 40000, 133,0 }, + {4229,4229, 0, 0, 40000, 86,0 }, + {4230,4230, 0, 0, 40000, 73,0 }, + {4231,4231, 0, 0, 40000, 106,0 }, + {4232,4233, 0, 1, 40000, 186,0.03125 }, + {4234,4235, 0, 1, 40000, 86,0.046875 }, + {4236,4237, 0, 1, 40000, 0,0.03125 }, + {4238,4238, 0, 0, 40000, 300,0 }, + {4239,4239, 0, 0, 40000, 66,0 }, + {4240,4241, 0, 1, 40000, 73,0.125 }, + {4242,4243, 0, 1, 40000, 86,0.109375 }, + {4244,4245, 0, 1, 40000, 146,0.109375 }, + {4246,4247, 0, 1, 40000, 66,-0.03125 }, + {4248,4248, 0, 0, 40000, 60,0 }, + {4249,4250, 0, 1, 40000, 213,0.15625 }, + {4251,4252, 0, 1, 40000, 66,0.125 }, + {4253,4254, 0, 1, 40000, 100,0.03125 }, + {4255,4256, 0, 1, 40000, 1513,0.078125 }, + {4257,4258, 0, 1, 40000, 353,0.109375 }, + {4259,4260, 0, 1, 40000, 133,0.078125 }, + {4261,4262, 0, 1, 40000, 746,0.140625 }, + {4263,4264, 0, 1, 40000, 0,0.109375 }, + {4265,4266, 0, 1, 5033, 1606,0.0625 }, + {4267,4268, 0, 1, 40000, 1146,0.09375 }, + {4269,4270, 0, 1, 40000, 1586,0.109375 }, + {4271,4272, 0, 1, 40000, 0,0.09375 }, + {4273,4274, 0, 1, 40000, 1006,0.125 }, + {4275,4275, 0, 1, 2680, 793,0.109375 }, + {4276,4277, 0, 1, 40000, 0,-0.046875 }, + {4278,4279, 0, 1, 9000, 3186,0.125 }, + {4280,4281, 0, 1, 40000, 1073,-0.078125 }, + {4282,4283, 0, 1, 40000, 2093,0.140625 }, + {4284,4285, 0, 1, 5640, 440,0.078125 }, + {4286,4287, 0, 1, 9580, 713,0.03125 }, + {4288,4289, 0, 1, 6286, 380,0 }, + {4290,4291, 0, 1, 2220, 426,0.03125 }, + {4292,4292, 0, 0, 1166, 760,0 }, + {4293,4294, 0, 1, 1186, 240,0 }, + {4295,4296, 0, 1, 40000, 100,0.0625 }, + {4297,4297, 0, 0, 40000, 160,0 }, + {4298,4298, 0, 0, 40000, 120,0 }, + {4299,4299, 0, 0, 8673, 2413,0 }, + {4300,4300, 0, 0, 393, 126,0 }, + {4301,4302, 0, 1, 1220, 393,0.03125 }, + {4303,4303, 0, 0, 246, 93,0 }, + {4304,4305, 0, 1, 1953, 393,0 }, + {4306,4307, 0, 1, 566, 146,0 }, + {4308,4309, 0, 1, 4220, 133,0 }, + {4310,4311, 0, 1, 2873, 73,0.109375 }, + {4312,4312, 0, 0, 613, 60,0 }, + {4313,4314, 0, 1, 40000, 186,0 }, + {4315,4316, 0, 1, 11880, 2993,0 }, + {4317,4317, 0, 0, 1573, 86,0 }, + {4318,4319, 0, 1, 40000, 793,0 }, + {4320,4321, 0, 1, 40000, 173,0 }, + {4322,4323, 0, 1, 40000, 793,0 }, + {4324,4324, 0, 0, 606, 133,0 }, + {4325,4325, 34, 0, 133, 40,0 }, + {4326,4326, 28, 0, 193, 46,0 }, + {4327,4328, 39, 1, 553, 126,0 }, + {4327,4328, 33, 1, 553, 126,0 }, + {4329,4330, 63, 1, 160, 80,0 }, + {4331,4331, 15, 0, 113, 0,0 }, + {4332,4332, 36, 0, 106, 0,0 }, + {4332,4333, 36, 1, 480, 173,0.40625 }, + {4334,4335, 25, 1, 313, 153,0 }, + {4336,4335, 25, 1, 206, 100,0 }, + {4337,4338, 61, 1, 153, 93,0 }, + {4339,4340, 37, 1, 206, 93,0 }, + {4341,4342, 15, 1, 346, 153,0 }, + {4343,4344, 48, 1, 280, 133,-1.90625 }, + {4345,4346, 19, 1, 553, 200,0 }, + {4347,4347, 48, 0, 180, 86,0 }, + {4348,4349, 15, 1, 333, 153,0 }, + {4350,4351, 12, 1, 340, 146,0 }, + {4352,4353, 11, 1, 346, 146,0 }, + {4354,4355, 61, 1, 2706, 1033,0.09375 }, + {4356,4353, 8, 1, 340, 146,0 }, + {4357,4358, 91, 1, 1166, 366,-0.046875 }, + {4359,4359, 70, 0, 966, 346,0 }, + {4360,4361, 80, 1, 300, 93,0.125 }, + {4362,4362, 58, 0, 206, 53,0 }, + {4363,4355, 62, 1, 2333, 820,0.09375 }, + {4364,4365, 31, 1, 773, 200,0 }, + {4366,4358, 91, 1, 1160, 360,-0.03125 }, + {4367,4368, 41, 1, 373, 113,0 }, + {4369,4370, 35, 1, 406, 126,0 }, + {4371,4372, 29, 1, 146, 106,0 }, + {4373,4374, 41, 1, 400, 126,0 }, + {4373,4374, 37, 1, 400, 126,0 }, + {4375,4376, 54, 1, 286, 133,0 }, + {4375,4377, 48, 1, 286, 126,0 }, + {4378,4379, 77, 1, 193, 93,0 }, + {4380,4381, 72, 1, 200, 93,0 }, + {4382,4382, 40, 0, 513, 0,0 }, + {4383,4383, 38, 0, 200, 20,0 }, + {4384,4384, 36, 0, 620, 20,0 }, + {4385,4386, 60, 1, 120, 80,0 }, + {4386,4387, 60, 1, 380, 80,0 }, + {4388,4388, 73, 0, 166, 33,0 }, + {4389,4390, 68, 1, 153, 40,0 }, + {4391,4392, 18, 1, 200, 80,0 }, + {4393,4394, 18, 1, 253, 73,0 }, + {4395,4395, 90, 0, 193, 20,0 }, + {4396,4396, 90, 0, 793, 40,0 }, + {4397,4398, 64, 1, 373, 73,0.03125 }, + {4399,4400, 80, 1, 406, 153,0.03125 }, + {4401,4402, 64, 1, 1866, 606,0 }, + {4403,4403, 67, 0, 106, 26,0 }, + {4404,4405, 50, 1, 173, 0,0 }, + {4406,4406, 36, 0, 4646, 0,0 }, + {4407,4407, 0, 0, 40000, 86,0 }, + {4408,4408, 0, 0, 40000, 73,0 }, + {4409,4409, 0, 0, 2433, 700,0 }, + {4410,4410, 0, 0, 1233, 26,0 }, + {4411,4411, 0, 0, 40000, 66,0 }, + {4412,4412, 0, 0, 40000, 60,0 }, + {4413,4413, 0, 0, 40000, 60,0 }, + {4414,4414, 0, 0, 40000, 66,0 }, + {4415,4415, 0, 0, 40000, 66,0 }, + {4416,4416, 0, 0, 40000, 0,0 }, + {4416,4416, 73, 0, 40000, 0,0 }, + {4417,4417, 0, 0, 40000, 60,0 }, + {4418,4418, 0, 0, 40000, 60,0 }, + {4419,4419, 0, 0, 7326, 2486,0 }, + {4420,4420, 0, 0, 4886, 1586,0 }, + {4421,4421, 0, 0, 646, 20,0 }, + {4422,4422, 0, 0, 253, 20,0 }, + {4422,4422, 12, 0, 253, 20,0 }, + {4423,4423, 0, 0, 640, 100,0 }, + {4423,4423, 1, 0, 640, 106,0 }, + {4424,4424, 0, 0, 133, 106,0 }, + {4424,4424, 23, 0, 133, 106,0 }, + {4425,4425, 0, 0, 653, 100,0 }, + {4426,4426, 0, 0, 4166, 1546,0 }, + {4427,4427, 0, 0, 40000, 73,0 }, + {4428,4428, 0, 0, 40000, 60,0 }, + {4429,4429, 0, 0, 40000, 53,0 }, + {4430,4430, 0, 0, 40000, 0,0 }, + {4431,4431, 0, 0, 246, 20,0 }, + {4432,4432, 0, 2, 6, 0,0 }, + {4433,4433, 0, 0, 4946, 233,0 }, + {4434,4434, 0, 0, 4946, 233,0 }, + {4435,4435, 0, 0, 4953, 240,0 }, + {4436,4436, 0, 0, 4946, 233,0 }, + {4437,4437, 0, 0, 18233, 46,0 }, + {4438,4438, 0, 0, 2386, 26,0 }, + {4439,4439, 0, 0, 4640, 633,0 }, + {4440,4440, 0, 0, 18466, 100,0 }, + {4441,4441, 0, 0, 18440, 66,-2 }, + {4442,4442, 0, 0, 18440, 6140,-2 }, + {4443,4443, 0, 0, 1206, 433,-2 }, + {4444,4444, 0, 0, 4626, 240,0 }, + {4445,4445, 0, 0, 726, 400,0 }, + {4446,4446, 0, 0, 5866, 73,0 }, + {4447,4447, 0, 0, 40000, 73,0 }, + {4448,4448, 0, 0, 40000, 73,0 }, + {4449,4449, 0, 0, 40000, 73,0 }, + {4450,4450, 0, 0, 40000, 73,0 }, + {4451,4451, 0, 0, 6500, 346,0 }, + {4452,4452, 0, 0, 6506, 346,0 }, + {4453,4453, 0, 0, 40000, 66,-2 }, + {4454,4454, 0, 0, 40000, 66,-2 }, + {4455,4455, 0, 0, 40000, 0,0 }, + {4456,4456, 0, 0, 40000, 46,0 }, + {4457,4457, 0, 0, 40000, 0,0 }, + {4457,4457, 0, 0, 40000, 0,-2 }, + {4458,4458, 0, 0, 2386, 26,0 }, + {4459,4459, 0, 0, 40000, 73,-2 }, + {4460,4460, 0, 0, 5866, 26,-2 }, + {4461,4461, 0, 0, 40000, 133,0 }, + {4462,4462, 0, 0, 40000, 133,0 }, + {4463,4463, 0, 0, 40000, 126,0 }, + {4464,4464, 0, 0, 253, 20,0 }, + {4465,4465, 0, 0, 8866, 1366,0 }, + {4466,4466, 0, 0, 1040, 766,0 }, + {4467,4467, 0, 0, 40000, 146,-2 }, + {4468,4468, 0, 0, 40000, 153,-2 }, + {4469,4469, 0, 0, 40000, 466,-2 }, + {4470,4470, 0, 0, 40000, 66,0 }, + {4471,4471, 0, 0, 2333, 566,0 }, + {4472,4472, 0, 0, 40000, 140,-2 }, + {4473,4473, 0, 0, 40000, 100,-2 }, + {4474,4474, 0, 0, 40000, 226,-2 }, + {4475,4475, 0, 0, 40000, 0,0 }, + {3712,3712, 0, 0, 40000, 226,-2 }, + {4476,4476, 0, 0, 40000, 140,-2 }, + {4477,4477, 0, 0, 40000, 66,0 }, + {4478,4478, 0, 0, 40000, 73,0 }, + {4479,4479, 0, 0, 40000, 73,0 }, + {4480,4480, 0, 0, 40000, 86,-2 }, + {4481,4481, 0, 0, 40000, 80,0 }, + {4482,4482, 0, 0, 40000, 73,-2 }, + {4483,4483, 0, 0, 40000, 80,-2 }, + {4484,4484, 0, 0, 40000, 73,-2 }, + {4485,4485, 0, 0, 40000, 73,0 }, + {4486,4486, 0, 0, 40000, 73,0 }, + {4487,4487, 0, 0, 40000, 93,0 }, + {4488,4488, 0, 0, 40000, 73,0 }, + {4489,4489, 0, 0, 11946, 13,0 }, + {4490,4490, 0, 0, 40000, 73,0 }, + {4460,4460, 0, 0, 5866, 26,0 }, + {4491,4491, 0, 0, 40000, 820,0 }, + {4492,4492, 0, 0, 2153, 873,0 }, + {1221,1221, 0, 0, 40000, 293,0.171875 }, + {4493,4493, 0, 0, 1620, 120,0 }, + {4494,4494, 0, 0, 15120, 93,0 }, + {4495,4495, 0, 0, 14613, 93,0 }, + {4496,4496, 0, 0, 2346, 793,0 }, + {4497,4497, 0, 0, 40000, 2380,0 }, + {4498,4498, 0, 0, 40000, 1280,0 }, + {4499,4499, 0, 0, 40000, 1460,0 }, + {4500,4500, 0, 0, 40000, 2513,0 }, + {4501,4501, 0, 0, 14840, 1266,0 }, + {4502,4502, 0, 0, 4513, 640,0 }, + {4503,4503, 0, 0, 4680, 806,0 }, + {4504,4504, 0, 0, 40000, 100,0 }, + {4505,4505, 0, 0, 40000, 66,0 }, + {4506,4506, 0, 0, 2420, 413,0 }, + {4507,4507, 0, 0, 406, 73,-2 }, + {4508,4508, 0, 0, 1166, 400,0 }, + {4509,4509, 0, 0, 1213, 106,0 }, + {4510,4510, 0, 0, 273, 60,-2 }, + {4511,4511, 0, 0, 40000, 2380,0 }, + {4512,4512, 0, 0, 40000, 440,0 }, + {1261,1261, 0, 0, 40000, 2960,0 }, + {4513,4513, 37, 0, 973, 73,-2 }, + {4514,4514, 48, 0, 106, 0,-2 }, + {4515,4515, 48, 0, 286, 133,-2 }, + {4516,4516, 62, 0, 166, 60,0 }, + {4517,4517, 44, 0, 980, 360,0 }, + {4518,4518, 80, 0, 100, 0,0 }, + {4517,4517, 50, 0, 980, 346,0 }, + {4519,4519, 48, 0, 106, 0,-2 }, + {4517,4517, 55, 0, 973, 360,0 }, + {4520,4520, 61, 0, 513, 20,0 }, + {4517,4517, 58, 0, 966, 353,0 }, + {4517,4517, 63, 0, 973, 353,0 }, + {4521,4521, 71, 0, 1366, 580,0 }, + {4517,4517, 72, 0, 820, 306,0 }, + {4522,4522, 70, 0, 1886, 666,0 }, + {4521,4521, 88, 0, 1353, 560,0 }, + {4523,4523, 76, 0, 1873, 653,0 }, + {4524,4524, 84, 0, 260, 113,0 }, + {4521,4521, 68, 0, 1366, 553,0 }, + {4525,4525, 72, 0, 153, 53,0 }, + {4526,4526, 28, 0, 1193, 413,0 }, + {4522,4522, 81, 0, 1353, 480,0 }, + {4527,4527, 58, 0, 246, 120,-2 }, + {4527,4527, 55, 0, 246, 120,-2 }, + {4527,4527, 44, 0, 246, 120,-2 }, + {4527,4527, 49, 0, 246, 120,-2 }, + {4527,4527, 40, 0, 286, 133,-2 }, + {4528,4528, 55, 0, 740, 560,-2 }, + {4528,4528, 48, 0, 893, 693,-2 }, + {4529,4529, 52, 0, 513, 206,0 }, + {4529,4529, 45, 0, 513, 206,0 }, + {4530,4530, 48, 0, 173, 100,-2 }, + {4531,4531, 48, 0, 120, 266,-2 }, + {4532,4532, 48, 0, 253, 60,-2 }, + {4507,4507, 73, 0, 160, 20,-2 }, + {4507,4507, 68, 0, 160, 20,-2 }, + {4507,4507, 63, 0, 193, 20,-2 }, + {4533,4533,108, 0, 406, 26,0 }, + {4534,4534,108, 0, 740, 26,0 }, }; @@ -9339,7 +9472,7 @@ const unsigned short banks[75][256] = 232, 233, 234, 235, 236, 237, 238, 239, 71, 72, 240, 241, 242, 243, 244, 245, 246, 247, 248, 82, 249, 250, 251, 86, 252, 253, 254, 255, 91, 92, 256, 257, 258, 259, 260, 98, 99, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 111, 272, 273, 274, 115, 275, 276, 277, 278, 120, 279, 280, 281, 282, 283, 284, + 111, 272, 273, 274, 115, 275, 276, 277, 278, 120, 279, 280, 281, 282, 295, 284, 127, 132, 285, 286, 127, 287, 288, 289, 290, 291, 292, 127, 127, 293, 294, 295, 289, 296, 297, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 318, 320, 318, 321, 318, @@ -9358,86 +9491,86 @@ const unsigned short banks[75][256] = 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 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, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 386, 387, 388, 389, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 385, 386, 387, 388, 389, 390, 391, 392, 369, 393, 308, 394, 395, 396, 397, 398, 399, 398, 400, 401, 402, 403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427, - 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { - 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, + 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, 79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 304, 470, 471, 472, 473, + 468, 469, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 304, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 345, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 355, 356, 357, 358, 359, 529, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 521, 522, 523, 524, 525, 526, 527, 528, 355, 356, 357, 358, 359, 529, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { - 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, + 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, 79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 433, 112, 99, 530, 531, 93, 532, 248, 107, 116, 533, 28, 78, 534, 535, - 536, 79, 94, 38, 33, 115, 537, 538, 539, 540, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 541, 542, 543, 544, 545, 546, 433, 295, + 468, 295, 112, 99, 530, 531, 93, 532, 248, 107, 116, 533, 28, 78, 534, 535, + 536, 79, 94, 38, 33, 115, 537, 538, 539, 540, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 541, 542, 543, 544, 545, 546, 295, 295, 547, 132, 134, 136, 138, 139, 141, 173, 156, 291, 292, 127, 548, 549, 550, 551, - 552, 362, 553, 143, 433, 433, 433, 433, 433, 433, 433, 304, 470, 471, 472, 473, + 552, 362, 553, 143, 295, 295, 295, 295, 295, 295, 295, 304, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 554, 555, 556, 557, 487, 488, 489, 490, 491, 492, 493, 558, 495, 496, 497, 498, 499, 500, 501, 559, 503, 504, 505, 506, 507, 508, 560, 561, 511, 512, 513, 514, 562, 563, 345, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 564, 356, 565, 358, 359, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 295, + 521, 522, 523, 524, 525, 526, 527, 528, 564, 356, 565, 358, 359, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { - 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, + 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, 79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 566, 567, 568, 569, + 468, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 566, 567, 568, 569, 570, 34, 571, 572, 437, 51, 52, 84, 573, 574, 575, 576, 577, 85, 530, 90, - 93, 94, 101, 578, 114, 119, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 293, 127, 548, + 93, 94, 101, 578, 114, 119, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 293, 127, 548, 550, 296, 297, 296, 297, 298, 299, 300, 301, 302, 303, 304, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 345, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 355, 356, 357, 358, 359, 360, 361, 362, - 164, 363, 156, 364, 292, 365, 366, 367, 368, 178, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 164, 363, 156, 364, 292, 365, 366, 367, 368, 178, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { - 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, + 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443, 79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 433, 579, 580, 581, 433, 433, 582, 433, 433, 433, 433, 583, 584, 585, 586, - 587, 444, 588, 589, 590, 433, 591, 592, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 577, 566, + 468, 295, 579, 580, 581, 295, 295, 582, 295, 295, 295, 295, 583, 584, 585, 586, + 587, 444, 588, 589, 590, 295, 591, 592, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 577, 566, 437, 90, 460, 28, 593, 594, 595, 596, 31, 597, 598, 28, 441, 442, 567, 530, - 93, 572, 599, 279, 30, 435, 100, 94, 575, 38, 281, 437, 447, 51, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 356, 357, 358, 359, 304, 470, 471, 472, 473, + 93, 572, 599, 279, 30, 435, 100, 94, 575, 38, 281, 437, 447, 51, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 356, 357, 358, 359, 304, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 345, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 355, 600, 601, 602, 127, 548, 296, 603, 604, 550, 605, 606, 362, 607, 135, 608, 361, 609, 610, 611, 612, 507, 146, 613, - 547, 500, 614, 364, 173, 615, 366, 600, 616, 617, 618, 619, 620, 621, 433, 433, + 547, 500, 614, 364, 173, 615, 366, 600, 616, 617, 618, 619, 620, 621, 295, 295, }, { 622, 179, 371, 180, 372, 373, 374, 375, 376, 377, 186, 378, 187, 379, 380, 190, @@ -9465,15 +9598,15 @@ const unsigned short banks[75][256] = 659, 599, 660, 661, 662, 68, 663, 664, 71, 665, 666, 74, 75, 667, 668, 669, 577, 85, 441, 442, 38, 84, 46, 86, 530, 88, 670, 90, 91, 92, 93, 94, 258, 671, 97, 532, 99, 100, 101, 672, 536, 673, 674, 675, 676, 677, 464, 110, - 678, 578, 113, 114, 679, 116, 680, 599, 31, 462, 279, 125, 465, 281, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 433, 433, 681, 682, 683, 500, 503, 614, 684, 685, 296, 552, 550, 605, 600, + 678, 578, 113, 114, 679, 116, 680, 599, 31, 462, 279, 125, 465, 281, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 681, 682, 683, 500, 503, 614, 684, 685, 296, 552, 550, 605, 600, 548, 602, 127, 601, 293, 549, 604, 551, 603, 298, 362, 299, 135, 300, 361, 301, 302, 547, 303, 142, 143, 144, 619, 146, 291, 686, 149, 687, 367, 368, 292, 365, 366, 364, 688, 158, 689, 690, 615, 162, 163, 164, 363, 691, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 692, 693, 694, 695, 696, 697, 698, 699, - 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 712, 713, 714, 715, 716, 713, 717, 718, 719, 720, 721, 722, 723, 724, 715, 725, @@ -9484,14 +9617,14 @@ const unsigned short banks[75][256] = 769, 770, 771, 664, 772, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 788, 789, 786, 753, 790, 780, 780, 780, 791, 791, 792, 793, 794, 795, 796, 680, 680, 797, 798, 799, 800, 801, 802, 803, 742, 804, - 805, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, + 805, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 821, 824, 825, 821, 826, 821, 827, 828, 829, 830, 831, 832, - 833, 834, 834, 835, 835, 825, 825, 836, 837, 838, 806, 839, 840, 841, 806, 806, - 842, 843, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, + 833, 834, 834, 835, 835, 825, 825, 836, 837, 838, 295, 839, 840, 841, 295, 295, + 842, 843, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, @@ -9502,14 +9635,14 @@ const unsigned short banks[75][256] = 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 295, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 971, 972, 973, 974, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 971, 972, 973, 974, 975, 310, 976, 977, 978, 974, 979, 980, 981, 982, 983, 984, 983, 985, 986, 987, 988, 989, 990, 325, 989, 325, 991, 989, 992, 989, 330, 993, 994, 995, 996, 997, 998, 999,1000,1001,1002,1003, 340,1004,1005,1006,1007,1008,1009, 310,1010,1011, -1012, 429,1003, 430,1013,1014, 974,1015, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 295, +1012, 429,1003, 430,1013,1014, 974,1015, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031, @@ -9520,14 +9653,14 @@ const unsigned short banks[75][256] = 1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110, 1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126, 1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 305, 306, 307, 308, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 305, 306, 307, 308, 1143, 425, 311,1144, 393, 308, 394, 395, 396, 397,1145, 399,1145, 400,1146, 402, 403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427, - 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 1147,1017,1018,1148,1149,1150,1022, 184,1024,1025,1026,1027,1028,1151,1152,1153, @@ -9538,14 +9671,14 @@ const unsigned short banks[75][256] = 1188,1189,1097,1098,1190,1100,1191,1192,1103,1193,1194,1195,1196,1197,1198,1199, 1111,1200,1201,1202,1203,1116,1204,1205,1119,1206,1207,1122,1123,1124,1125,1208, 1127,1209,1210,1130,1131,1211,1212,1213,1135,1214,1215,1138,1139,1216,1217,1218, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 386, 387, 388, 389, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 385, 386, 387, 388, 389, 390, 391, 392,1219,1219, 308, 394, 395, 396, 397, 398, 399, 398, 400, 401, 402, 403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413, 414, 415, 416,1220,1221, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427, - 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -9578,7 +9711,7 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 312,1349,1350,1351,1352,1353,1354, 319,1355, 320,1356, 321,1357, 1358,1359,1360,1361,1362,1363,1364,1365,1366,1359,1367,1361, 332, 333, 334, 335, - 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371, + 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295, 347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -9596,7 +9729,7 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 312,1349,1350,1351,1352,1382,1354, 319,1355, 320,1356, 321,1357, 1358,1359,1360,1361,1362,1363,1364,1383,1366,1359,1384,1361, 332, 333, 334, 335, - 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371, + 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295, 347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -9614,7 +9747,7 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 312,1349,1350,1351,1352,1353,1354, 319,1355, 320,1356, 321,1357, 1358,1359,1360,1361,1362,1363,1364,1383,1366,1359,1387,1361, 332, 333, 334, 335, - 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371, + 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295, 347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -9681,7 +9814,7 @@ const unsigned short banks[75][256] = 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587, 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594, 1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284, +1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 127, 127,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623, @@ -9790,14 +9923,14 @@ const unsigned short banks[75][256] = 2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2071,2072,2073, 2074,2075,2076,2077,2078,2079,2080, 275,2081,2082,1527,2083,2084,2085,2086,2087, 2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099, 122,2100,2101,2102, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113, -2115, 547,2115,2116,2103,2103,2117,2103,2118,2103,2103,2103,2119,2120,2121,2122, -2123,2124,2125,2126,2127, 160, 161, 162, 163,2128,2103,2129,2103,2103,2103,2103, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2103, 295,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113, +2115, 547,2115,2116, 295, 295,2117, 295,2118, 295, 295, 295,2119,2120,2121,2122, +2123,2124,2125,2126,2127, 160, 161, 162, 163,2128, 295,2129, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 2130,2130,2130,2130,2130,2130, 727,2131,2132,2133,2134,2135,2136,2137,2138,2139, @@ -9879,7 +10012,7 @@ const unsigned short banks[75][256] = 232, 233, 234, 235,2281, 237, 238, 239,1584,1585,2282,1586, 242, 243, 244,1587, 246, 247,1588,1589, 249, 250, 251,1590,2283, 253, 254, 255,1591,1592,1593,1594, 1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284, +1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2284, 295, 295, 295,2284,2285,2286,1614,1615,2287,2288,1618,1619,1620,1621,1622,1623, @@ -9969,7 +10102,7 @@ const unsigned short banks[75][256] = 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587, 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594, 1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284, +1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2430,2430,2431,2432,2433,2434,2435,2436,2437,2436,2438,2436,2439, @@ -10005,7 +10138,7 @@ const unsigned short banks[75][256] = 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587, 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594, 1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284, +1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 127, 127,2286,1614,1615,1616,2288,1618,1619,1620,1621,1622,1623, @@ -10045,7 +10178,7 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2493, 295,2555, 295,2556,2495,2557,2558,2559,2496,2497,2560,2498,2561,2499,2562,2500, -2563,2564,2565,2527, 295, 295,2566, 295,2567, 295, 295, 295,2570,2571, 295,2572, +2563,2564,2565,2527, 295, 295,2566, 295, 295, 295, 295, 295,2570,2571, 295,2572, 2573, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -10131,7 +10264,7 @@ const unsigned short banks[75][256] = 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,2873, 242, 243, 244,2874, 246, 247,1588,1589, 249,2875,2876,2877,2878, 253, 254, 255,1591,1592,1593,2879, 1595, 259,1596,2880,1598,1599,1600,1601, 264, 265, 266,2881, 268, 108, 270,2859, -2882,2883, 273,1603,1604,1605, 276,2884,2885,2886,1609,1610,2887,1612,2888, 284, +2882,2883, 273,1603,1604,1605, 276,2884,2885,2886, 295,1610,2887,1612,2888, 284, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2889,2889, 128, 129, 130,2890, 132,2891, 134, 135, 136, 137, 138, @@ -10168,14 +10301,14 @@ const unsigned short banks[75][256] = 2968,2969,2554,2970,2489,2971,2972,2973, 657, 575,2974,2975,2976, 779,2977,2978, 2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2553,2989,2990,2991,2992,2993, 2994,2995, 680, 796,2996, 797,2662,2997,2998,2999,2514,3000,3001,1913,3002,3003, - 295, 295, 295, 295, 295, 295, 295, 295, 295, 384, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,3004, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,1219,1219, 308, 394, 395, 396, 397, 398, 399, 398, 400, 401, 402, 403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413, 414, 415, 416,1220,1221, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427, - 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 2501,2502,2503,2504,2505,2506,2507, 730,2508,2509,2510,2511,2512,2513,2514,2515, @@ -10189,7 +10322,7 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2493, 295,2555, 295,2556,2495,2557,2558,2559,2496,2497,2560,2498,2561,2499,2562,2500, -2563,3011,2565,2527, 295, 295,2566, 295,2567, 295, 295, 295,3012,3013,3014,3015, +2563,3011,2565,2527, 295, 295,2566, 295, 295, 295, 295, 295,3012,3013,3014,3015, 3016,3015,3016, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -10240,14 +10373,14 @@ const unsigned short banks[75][256] = 2059,2060,2061,2062,2063,2064,2065,2066,3089,2068,2069,2070,3090,3091,2072,2073, 2074,2075,2076,2077,2078,2079,2080, 275,2081,2082,1527,2083,2084,2085,2086,2087, 2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099, 122,2100,2101,2102, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113, -2115, 547,2115,2116,2103,2103,2117,2103,2118,2103,2103,2103,2119,2120,2121,2122, -2123,2124,2125,2126,2127, 160, 161, 162, 163,2128,2103,2129,2103,2103,2103,2103, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2103, 295,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, -2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113, +2115, 547,2115,2116, 295, 295,2117, 295,2118, 295, 295, 295,2119,2120,2121,2122, +2123,2124,2125,2126,2127, 160, 161, 162, 163,2128, 295,2129, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 2501,2502,2503,2504,2505,2506,2507, 730,2508,2509,2510,2511,2512,2513,2514,2515, @@ -10261,75 +10394,75 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2493, 295,2555, 295,3092,2495,2557,2558,2559,2496,2497,2562,2498,2561,2499,2562,2500, -2563,3011,2565,2527, 295, 295,2566, 295,2567, 295, 295, 295,2570,2571, 295,2572, +2563,3011,2565,2527, 295, 295,2566, 295, 295, 295, 295, 295,2570,2571, 295,2572, 3093, 295, 295, 295, 295, 295,3094, 295, 295,3095,3096, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,3097, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -1551,1552,1553,3101, 181, 182, 183,3102, 185,1556,1557,3103,1559, 188, 189,1560, -1561,1562, 193,1564,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205, - 206, 207, 208,1568,1569,1570,1571, 211,1572,1573, 214, 215, 216, 217, 218, 219, - 220, 221,1574,1575,1576,1577,1578, 225,1579,1580,3100,1581,1582, 229, 230, 231, - 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587, - 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594, -1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,3104,3105, 283, 284, +3098,3205,3101,3129,3130,3131,3108,3132,3209,3210,3120,3133,3124,3134,3103,3135, +3136,3137,3113,3138,3139,3140,3141,3142,3143,3144,3145,3206,3121,3207,3208,3146, +3127,3147,3148,3211,3212,3149,3150,3151,3116,3106,3152,3110,3111,3213,3104,3126, +3105,3117,3153,3154,3102,3214,3155,3119,3215,3216,3115,3109,3217,3114,3112,3218, +3156,3219,3157,3158,3159,3107,3122,3128,3160,3222,3161,3162,3163,3164,3165,3166, +3167,3168,3169,3170,3171,3172,3173,3174,3223,3175,3176,3177,3118,3221,3220,3178, +3226,3241,3179,3180,3242,3181,3182,3183,3184,3185,3186,3187,3125,3188,3189,3190, +3191,3192,3193,3194,3123,3195,3196,3197,3198,3224,3199,3200,3201,3202,3203,3204, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 127,3107,3122,3126, 316,3123,3121,3124,3107,3125,3107,3127,3107, -3107, 329,3107,3108,3143,3109,3128,3129,3099,3144,1634,3110,3130,3131,3117,3119, -3136,3132,3133,3134,3137,3115,3138,3135,3098, 343, 344,3112,3113,3113,3142,3139, -3140,3141,3116,3106,3111,3114,3118,3120, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 127,3227,3244,3248,3268,3245,3243,3246,3227,3247,3227,3249,3227, +3227,3269,3227,3228,3270,3229,3250,3251,3100,3271,3258,3230,3252,3253,3237,3239, +3259,3254,3255,3256,3260,3235,3261,3257,3099,3265,3266,3232,3233,3233,3267,3262, +3263,3264,3236,3225,3231,3234,3238,3240, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -1551,1552,1553,3101, 181, 182, 183,3102, 185,1556,1557,3103,1559, 188, 189,1560, -1561,1562, 193,1564,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205, - 206, 207, 208,1568,1569,1570,1571, 211,1572,1573, 214, 215, 216, 217, 218, 219, - 220, 221,1574,1575,1576,1577,1578, 225,1579,1580,3100,1581,1582, 229, 230, 231, - 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587, - 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594, -1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,3104,3105, 283, 284, +3098,3205,3101,3129,3130,3131,3108,3132,3209,3210,3120,3133,3124,3134,3103,3135, +3136,3137,3113,3138,3139,3140,3141,3142,3143,3144,3145,3206,3121,3207,3208,3146, +3127,3147,3148,3211,3212,3149,3150,3151,3116,3106,3152,3110,3111,3213,3104,3126, +3105,3117,3153,3154,3102,3214,3155,3119,3215,3216,3115,3109,3217,3114,3112,3218, +3156,3219,3157,3158,3159,3107,3122,3128,3160,3222,3161,3162,3163,3164,3165,3166, +3167,3168,3169,3170,3171,3172,3173,3174,3223,3175,3176,3177,3118,3221,3220,3178, +3226,3241,3179,3180,3242,3181,3182,3183,3184,3185,3186,3187,3125,3188,3189,3190, +3191,3192,3193,3194,3123,3195,3196,3197,3198,3224,3199,3200,3201,3202,3203,3204, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295,2430,2430,3149,3147,3148,3147,3145,3145,3145,3145,3145,3145,3145, -3145,3145,3145,3145,3145,3145,3150,3151,3173, 329,3152, 329,3153,3154,3155,3156, -3157,3158,3159,3160,3161, 349,3162,3163,3164,3165,3166,3148,3148,3148,3167,3168, -3169,3170, 349,3171,3172,3148,3155,3156,3146, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,3274,3274,3277,3275,3276,3275,3272,3272,3272,3272,3272,3272,3272, +3272,3272,3272,3272,3272,3272,3278,3279,3301,3269,3280,3269,3281,3282,3283,3284, +3285,3286,3287,3288,3289, 349,3290,3291,3292,3293,3294,3276,3276,3276,3295,3296, +3297,3298, 349,3299,3300,3276,3283,3284,3273, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,3189, -3190,3191,3192,3193,3194,3195,3196,3196,3197,3198,3199,3200,3201,3202,3203,3204, -3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,3219,3220, -3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3196,3232,3233,3234,3235, -3196,3236,3237,3238,3196,3239,3196,3240,3196,3241,3196,3242,3196,3243,3244,3245, -3246,3247,3248,3196,3249,3250,3196,3251,3252,3253,3254,3255,3196,3196,3256,3196, -3257,3196,3258,3196,3259,3260,3196,3261,3196,3196,3262,3196,3196,3196,3196,3196, -3196,3196,3196,3263,3196,3196,3196,3196,3196,3196,3264,3265,3196,3196,3196,3196, -3266,3267, 285,3268,3269, 287, 288,3270,3271,3271,3271,3271,3271,3271,3271,3271, -3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271, -3271,3271,3271,3272,3273,3271,3274,3271,3275,3276,3277,3278,3279,3280,3281,3282, -3282,3283,3280,3284,3271,3271,3285,3286,3271,3271,3271,3271,3271,3271,3271,3271, -3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271, -3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271, -3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271, -3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271, +3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3312,3313,3314,3315,3316,3317, +3318,3319,3320,3321,3322,3323,3324,3324,3325,3326,3327,3328,3329,3330,3331,3332, +3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343,3344,3345,3346,3347,3348, +3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3324,3360,3361,3362,3363, +3324,3364,3365,3366,3324,3367,3324,3368,3324,3369,3324,3370,3324,3371,3372,3373, +3374,3375,3376,3324,3377,3378,3324,3379,3380,3381,3382,3383,3324,3324,3384,3324, +3385,3324,3386,3324,3387,3388,3324,3389,3324,3324,3390,3324,3324,3324,3324,3324, +3324,3324,3324,3391,3324,3324,3324,3324,3324,3324,3392,3393,3324,3324,3324,3324, +3394,3395, 285,3396,3397, 287, 288,3398,3399,3399,3399,3399,3399,3399,3399,3399, +3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399, +3399,3399,3399,3400,3401,3399,3402,3399,3403,3404,3405,3406,3407,3408,3409,3410, +3410,3411,3408,3412,3399,3399,3413,3414,3399,3399,3399,3399,3399,3399,3399,3399, +3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399, +3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399, +3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399, +3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399, }, { -3287,3288, 466,3289, 713,3196,3290, 467,3291, 632,3292,3293,3294,3295,3296,3297, -3298, 598,3299,3300,3301,3302,3303,3304,1512,3305,3294,3306, 759, 437, 437,3307, -3308,3309, 439,3310, 440,3311, 442, 441,3312,3313,3314,3315,2306,3316,3317, 582, -3318,3319, 452,3320,3321,3290,3322,3323,3324, 778,3325,2312, 779,3326,3327,3328, -3329, 769,3330,3331,3332,3333, 663, 664,3334,2316,3335,3336,3337,1299,3338,3339, -3340,3341,3342,3343,3344,3345,3346, 442,3347,3348,3349,3304,3350,1669,3351,3352, -3353,3354,3355,3356,3353, 261,3357,3358,1919,2420,3359,3360, 676,3361,3362,3363, -3364,3365,3366,3367, 677,3368, 677,3369,3370, 677,3371, 455,3372,2421,3373, 465, +3415,3416, 466,3417, 713,3324,3418, 467,3419, 632,3420,3421,3422,3423,3424,3425, +3426, 598,3427,3428,3429,3430,3431,3432,1512,3433,3422,3434, 759, 437, 437,3435, +3436,3437, 439,3438, 440,3439, 442, 441,3440,3441,3442,3443,2306,3444,3445, 582, +3446,3447, 452,3448,3449,3418,3450,3451,3452, 778,3453,2312, 779,3454,3455,3456, +3457, 769,3458,3459,3460,3461, 663, 664,3462,2316,3463,3464,3465,1299,3466,3467, +3468,3469,3470,3471,3472,3473,3474, 442,3475,3476,3477,3432,3478,1669,3479,3480, +3481,3482,3483,3484,3481, 261,3485,3486,1919,2420,3487,3488, 676,3489,3490,3491, +3492,3493,3494,3495, 677,3496, 677,3497,3498, 677,3499, 455,3500,2421,3501, 465, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -10340,14 +10473,14 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3374,3374,3375,3376,3377,3378,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387, -3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403, -3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,3414,3415,3416,3417,3418,3419, -3420,3421,3422,3423,3424,3425,3426,3427,3425,3428,3429,3430,3431,3432,3433,3434, -3435,3436,3437,3438,3439,3440,3441,3442,3443,3444,3445,3446,3335,3447,3448,3449, -3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,3460,3461,3462,3462,3463,3464, -3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3479,3480, -3481,3482,3481,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3493,3494,3495, +3502,3502,3503,3504,3505,3506,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515, +3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531, +3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547, +3548,3549,3550,3551,3552,3553,3554,3555,3553,3556,3557,3558,3559,3560,3561,3562, +3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3463,3575,3576,3577, +3578,3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3590,3591,3592, +3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608, +3609,3610,3609,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, @@ -10369,155 +10502,155 @@ const unsigned short banks[75][256] = 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,3496, 150, 151, 152, 153, 154, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,3624, 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, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -1551,1552,1553,1554, 181, 182, 183,1555, 185,1556,3497,3498,3499, 188, 189,1560, -1561,1562,1563,3500,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205, - 206, 207, 208,1568,1569,1570,1571,3501,1572,1573, 214, 215, 216, 217, 218, 219, +1551,1552,1553,1554, 181, 182, 183,1555, 185,1556,3625,3626,3627, 188, 189,1560, +1561,1562,1563,3628,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205, + 206, 207, 208,1568,1569,1570,1571,3629,1572,1573, 214, 215, 216, 217, 218, 219, 220, 221,1574,1575,1576,1577,1578, 225,1579,1580, 226,1581,1582, 229, 230, 231, 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587, 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594, 1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271, -1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,3502,3503, 283, 284, +1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,3630,3631, 295, 284, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 127,3504,1613,1614,3505,1616,3506,1618,3507,1620,3508,1622,3509, -3510,1625,3511,3512,1628,1629,1630,1631,3513,1633,1634,3514,1636,1637,1638,1639, + 295, 295, 295, 127,3632,1613,1614,3633,1616,3634,1618,3635,1620,3636,1622,3637, +3638,1625,3639,3640,1628,1629,1630,1631,3641,1633,1634,3642,1636,1637,1638,1639, 1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655, 1656,1657,1658,1659,1660,1661,1662,1663, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3515,3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530, -3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546, -3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562, -3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578, -3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594, -3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610, -3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626, -3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,3639,3640,3641,3642, -3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643, -3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643, -3643,3643,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656, -3657,3658,3659,3660,3658,3661,3662,3658,3663,3658,3664,3665,3666,3667,3668,3669, -3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685, -3686,3687, 806, 806, 806, 806, 806,3643,3643,3643,3643,3643,3643,3643,3643,3643, -3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643, -3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643, +3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658, +3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674, +3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690, +3691,3692,3693,3694,3695,3696,3697,3698,3699,3700,3701,3702,3703,3704,3705,3706, +3707,3708,3709,3710,3711,3712,3713,3714,3715,3716,3717,3718,3719,3720,3721,3722, +3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738, +3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754, +3755,3756,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784, +3785,3786,3787,3788,3786,3789,3790,3786,3791,3786,3792,3793,3794,3795,3796,3797, +3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813, +3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3287,1492,3688,3289, 713,3689,3690, 730,1914,3691,1533,3293,3692,3693,3694,3695, -3298,3696,3697,3698,3699,3700,3701,3702,3703,3704,3705,3706, 759, 437,3707,3708, -3308,3709,3710,3711,3712,3713, 442,3714,3715,3716,3717,3718,3719,3720,3721,3722, -3723,2306,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737, -3738,3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,3751,3752,3753, -3754,3755,3756,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769, -3770,3771,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785, -3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,3371,3796,3797,2421,3798,3799, +3415,1492,3816,3417, 713,3817,3818, 730,1914,3819,1533,3421,3820,3821,3822,3823, +3426,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,3834, 759, 437,3835,3836, +3436,3837,3838,3839,3840,3841, 442,3842,3843,3844,3845,3846,3847,3848,3849,3850, +3851,2306,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,3864,3865, +3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,3879,3880,3881, +3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897, +3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,3910,3911,3912,3913, +3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3499,3924,3925,2421,3926,3927, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656, -3657,3658,3659,3660,3658,3661,3662,3658,3663,3658,3664,3665,3666,3667,3668,3669, -3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685, -3686,3687, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784, +3785,3786,3787,3788,3786,3789,3790,3786,3791,3786,3792,3793,3794,3795,3796,3797, +3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813, +3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815, -3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831, -3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847, -3840,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862, -3863,3864,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877, -3878,3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893, -3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909, -3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925, -3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926, -3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926, -3926,3926,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939, -3940,3941,3942,3660,3943,3944,3662,3945,3663,3946,3947,3665,3948,3949,3950,3951, -3952,3953,3954,3955,3956,3936,3676,3957,3958,3679,3959,3960,3961,3962,3684,3685, -3963,3964,3965,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926, -3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926, -3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926, +3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943, +3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959, +3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975, +3968,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990, +3991,3992,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005, +4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021, +4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037, +4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067, +4068,4069,4070,3788,4071,4072,3790,4073,3791,4074,4075,3793,4076,4077,4078,4079, +4080,4081,4082,4083,4084,4064,3804,4085,4086,3807,4087,4088,4089,4090,3812,3813, +4091,4092,4093, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815, -3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3830,3966,3831, -3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3967,3845,3846,3847, -3840,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3968,3862, -3863,3864,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877, -3969,3879,3970,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893, -3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3971,3972,3973,3907,3908,3909, -3910,3911,3912,3913,3974,3915,3916,3975,3918,3919,3920,3921,3922,3923,3924,3925, -3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976, -3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3977,3977,3977,3977,3978, -3977,3977,3977,3927,3928,3979,3930,3931,3932,3980,3934,3935,3936,3937,3938,3939, -3940,3941,3942,3660,3943,3944,3662,3945,3663,3946,3947,3665,3948,3949,3950,3951, -3952,3953,3954,3955,3956,3936,3676,3957,3958,3981,3982,3960,3983,3984,3684,3685, -3963,3964,3965,3977,3977,3977,3977,3977,3977,3976,3985,3985,3985,3985,3985,3985, -3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985, -3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985, +3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943, +3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3958,4094,3959, +3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,4095,3973,3974,3975, +3968,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,4096,3990, +3991,3992,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005, +4097,4007,4098,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021, +4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4099,4100,4101,4035,4036,4037, +4038,4039,4040,4041,4102,4043,4044,4103,4046,4047,4048,4049,4050,4051,4052,4053, +4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104, +4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4105,4105,4105,4105,4106, +4105,4105,4105,4055,4056,4107,4058,4059,4060,4108,4062,4063,4064,4065,4066,4067, +4068,4069,4070,3788,4071,4072,3790,4073,3791,4074,4075,3793,4076,4077,4078,4079, +4080,4081,4082,4083,4084,4064,3804,4085,4086,4109,4110,4088,4111,4112,3812,3813, +4091,4092,4093,4105,4105,4105,4105,4105,4105,4104,4113,4113,4113,4113,4113,4113, +4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113, +4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113, }, { 1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237, -1238,1239,1240,1241,1242,1243,1244,1245,3986,3987,3988,1249,1250,1376,1377,1253, -1378,1255,1256,3989,1380,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,3990, -1270,3991,3992,3993,3994,1275,1276,1277,1278,1279,1381,1281,1282,1283,1284,1285, +1238,1239,1240,1241,1242,1243,1244,1245,4114,4115,4116,1249,1250,1376,1377,1253, +1378,1255,1256,4117,1380,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,4118, +1270,4119,4120,4121,4122,1275,1276,1277,1278,1279,1381,1281,1282,1283,1284,1285, 1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301, -1302,1303,1304,1305,3995,1307,1308,1309,1309,1310,1311,1312,1313,1314,1315,1316, +1302,1303,1304,1305,4123,1307,1308,1309,1309,1310,1311,1312,1313,1314,1315,1316, 1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332, -1333,1334,1335,1336,1337,3996,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348, +1333,1334,1335,1336,1337,4124,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 312,1349,1350,3997,1352,3998,1354,3999,1355, 320,1356, 321,1357, + 295, 295, 295, 312,1349,1350,4125,1352,4126,1354,4127,1355, 320,1356, 321,1357, 1358,1359,1360,1361,1362,1363,1364,1383,1366,1359,1384,1361, 332, 333, 334, 335, - 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371, + 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295, 347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -4000,4001,4002,4003,4004,4005, 6, 7,4006, 9, 10,4007, 12, 13, 14, 15, -4008,4009,4010,4011, 20,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022, - 32,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036, 46, -4037,4038,4039,4040,4041,4042,4043, 54,4044,4045,4046,4047,4048,4049,4050,4051, -4052,4053,4054, 66,4055,4056, 69,4057,4058,4059,4060, 74, 75, 76, 77, 78, -4061,4062,4063, 82,4064,4065, 85,4066,4067, 88,4068,4069,4070,4071,4072,4073, - 95, 96, 97,4074,4075,4076,4077, 102, 103,4078, 105, 106, 107,4079,4080,4081, -4082, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,4083,4084,4085, 125,4086, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656, -3657,3658,3659,3660,3658,3661,3662,3658,3663,3658,3664,3665,3666,3667,3668,3669, -3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685, -3686,3687, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, +4128,4129,4130,4131,4132,4133, 6, 7,4134, 9, 10,4135, 12, 13, 14, 15, +4136,4137,4138,4139, 20,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150, + 32,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,4164, 46, +4165,4166,4167,4168,4169,4170,4171, 54,4172,4173,4174,4175,4176,4177,4178,4179, +4180,4181,4182, 66,4183,4184, 69,4185,4186,4187,4188, 74, 75, 76, 77, 78, +4189,4190,4191, 82,4192,4193, 85,4194,4195, 88,4196,4197,4198,4199,4200,4201, + 95, 96, 97,4202,4203,4204,4205, 102, 103,4206, 105, 106, 107,4207,4208,4209, +4210, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,4211,4212,4213, 125,4214, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784, +3785,3786,3787,3788,3786,3789,3790,3786,3791,3786,3792,3793,3794,3795,3796,3797, +3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813, +3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3287,3288, 466,3289, 713,3196,3290, 467,3291, 632,3292,3293,3294,3295,4087,3297, -3298, 598,4088,3300,3301,3302,3303,3304,4089,4090,4091,4092, 759, 437, 438,3307, -3308,3309, 439,3310, 440,4093, 442,4094,3312,3313,3314,3315,2306,4095,3317, 582, -3318,3319, 452,3320,3321,4096,3322,3323,3324, 778,3325,2312, 779,3326,3327,3328, -3329, 769,3330,3331,3332,3333, 663, 664,3334,2316,3335,3336,3337,1299,3338,3339, -3340,3341,4097,3343,3344,3345,4098, 442,3347,3348,3349,3304,3350,1669,3351,3352, -3353,3354,3355,3356,4099, 261,3357,3358,1919,2420,3359,3360, 676,3361,3362,3363, -3364,4100,3366,3367,4101,4102, 680,3369,3370, 462,3371, 455,3372,2421,3373, 465, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806,3644,3645,4103,3649,3648,4104,4105,4106,4107,4108,4109,4110,4111, -4112,3658,4113,3660,3658,3661,3662,3658,3663,3658,3664,2617,3666,3667,3668,3669, -3670,3671,3672,3673,3674, 160,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685, -3686,3687, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, +3415,3416, 466,3417, 713,3324,3418, 467,3419, 632,3420,3421,3422,3423,4215,3425, +3426, 598,4216,3428,3429,3430,3431,3432,4217,4218,4219,4220, 759, 437, 438,3435, +3436,3437, 439,3438, 440,4221, 442,4222,3440,3441,3442,3443,2306,4223,3445, 582, +3446,3447, 452,3448,3449,4224,3450,3451,3452, 778,3453,2312, 779,3454,3455,3456, +3457, 769,3458,3459,3460,3461, 663, 664,3462,2316,3463,3464,3465,1299,3466,3467, +3468,3469,4225,3471,3472,3473,4226, 442,3475,3476,3477,3432,3478,1669,3479,3480, +3481,3482,3483,3484,4227, 261,3485,3486,1919,2420,3487,3488, 676,3489,3490,3491, +3492,4228,3494,3495,4229,4230, 680,3497,3498, 462,3499, 455,3500,2421,3501, 465, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,3772,3773,4231,3777,3776,4232,4233,4234,4235,4236,4237,4238,4239, +4240,3786,4241,3788,3786,3789,3790,3786,3791,3786,3792,2617,3794,3795,3796,3797, +3798,3799,3800,3801,3802, 160,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813, +3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { 622, 179, 371, 180, 372, 373, 374, 375, 376, 377, 186, 378, 187, 379, 380, 190, @@ -10530,106 +10663,106 @@ const unsigned short banks[75][256] = 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127,4114,4115,4116, 141,4117,4118,4119,4118,4120,4118,4121,4122, -4123,1954,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,4135,4136,4137, -4138,4139,4140,4141,4142,4143, 163,4144, 625,4145,4146,4147,4148,4149,4150,4151, -4152,4153,4154,4155,4156,4157,4158, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127,4242,4243,4244, 141,4245,4246,4247,4246,4248,4246,4249,4250, +4251,1954,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, +4266,4267,4268,4269,4270,4271, 163,4272, 625,4273,4274,4275,4276,4277,4278,4279, +4280,4281,4282,4283,4284,4285,4286, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, }, { -4159,4160,1553,1554, 181,4161,4162,1555, 185,4163,3497,4164,1559, 188,4165,4166, -4167,1562,4168,4169,1565, 195,4170, 197,4171,4172, 200, 201, 28,1566,1567,4173, -4174,4175,4176,4177,4178,4179,4180,4181,1572,1573, 214, 215, 216, 217, 218, 219, - 220,4182,4183,1575,1576,1577,1578,4184,1579,1580,4185,1581,4186,4187,4188,4189, - 232, 233, 234, 235,4190, 237, 238,4191,1584,1585, 240,1586, 242, 243, 244,1587, - 246,4192,4193,1589, 249, 250, 251,1590, 252,4194, 254, 255,4195,4196,4197,4198, -1595,4199,1596,1597,1598,1599,1600,1601,4200,4201,4202, 267,4203,4204, 270,4205, -4206,4207, 273,1603,4208,1605, 276,4209,4210,4211,4212,1610,4213,4214,4215, 126, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806,4216,1470,1613,4217,1615,4218,1475,4219,1477,4220,1479,4221,1481, -1482,4222,1484,4223,4224,4225,1630,4226,2291,4227,1634,3514,1636,1637,1638,1639, -1640,4228,4229,1643,1644,1645,1646,4230, 342,4231,4232,1651,1652,1653,4233,4234, -1656,4235,1658,1659,1660,1661,1662,1663, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, +4287,4288,1553,1554, 181,4289,4290,1555, 185,4291,3625,4292,1559, 188,4293,4294, +4295,1562,4296,4297,1565, 195,4298, 197,4299,4300, 200, 201, 28,1566,1567,4301, +4302,4303,4304,4305,4306,4307,4308,4309,1572,1573, 214, 215, 216, 217, 218, 219, + 220,4310,4311,1575,1576,1577,1578,4312,1579,1580,4313,1581,4314,4315,4316,4317, + 232, 233, 234, 235,4318, 237, 238,4319,1584,1585, 240,1586, 242, 243, 244,1587, + 246,4320,4321,1589, 249, 250, 251,1590, 252,4322, 254, 255,4323,4324,4325,4326, +1595,4327,1596,1597,1598,1599,1600,1601,4328,4329,4330, 267,4331,4332, 270,4333, +4334,4335, 273,1603,4336,1605, 276,4337,4338,4339,4340,1610,4341,4342,4343, 126, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,4344,1470,1613,4345,1615,4346,1475,4347,1477,4348,1479,4349,1481, +1482,4350,1484,4351,4352,4353,1630,4354,2291,4355,1634,3642,1636,1637,1638,1639, +1640,4356,4357,1643,1644,1645,1646,4358, 342,4359,4360,1651,1652,1653,4361,4362, +1656,4363,1658,1659,1660,1661,1662,1663, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3643, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, + 295, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871,2216, 873, 874, 875, 876, 877, 878,2217, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894,2218, 896, 897, 898, 899, 900,2219,2220, 903,2221, 905,2222,2223, 2224, 909,2225, 911, 912,2226,2227, 915, 916,2228,2229, 919, 920, 921, 922, 923, -2230, 925, 926, 927, 928, 929,4236, 931, 932, 933, 934, 935,2232,2233, 938,2234, - 940,4237, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, - 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966,4238, 968,4239,3643,3643, -4240,4241,4242,4243,4244,4245,4246, 978,4247,4248,4249,4250,4251,4252,4253,4254, -4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, 975, 971, 972, 973, 974, +2230, 925, 926, 927, 928, 929, 295, 931, 932, 933, 934, 935,2232,2233, 938,2234, + 940, 295, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, + 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966,4366, 968,4367, 295, 295, +4368,4369,4370,4371,4372,4373,4374, 978,4375,4376,4377,4378,4379,4380,4381,4382, +4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393, 975, 971, 972, 973, 974, 975, 310, 976, 977, 978, 974,2239, 980,2240, 982,2241, 984,2242, 985,2243, 987, 988,2244, 990, 325,2244, 325, 991,2244,2245,2246, 330, 993,2247,2248,2249, 997, 998,2250,2251,1001,1002,1003, 340,1004,1005,1006,1007,1008,1009, 310,1010,1011, -2252, 429,1003, 430,1013,1014, 974,1015,4266,4266,4266,4266,4266,4266,4266,4266, -4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266, -4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266, +2252, 429,1003, 430,1013,1014, 974,1015, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -3287,4267,3196,3196,4268,3196,3196,3196,3196,3196,3196, 378,3196,3196,3694,3196, -3196,4269,3196,4270,4271,4272,3196,3196,3196, 370,3196,4273,4274,4275,4276,4277, -3196,4278,4279,4280,3310,3310,4281, 442,4282,3196,3196,4283,4284,4283, 676,4285, -4286,3196,3196,4287, 51,3196,3196,3196,4288,3324,4289,3196, 59,4290,4288, 62, -3196,4291,4291,4292, 67,3196, 664,4293,3196,2316,3196,4294, 70,3196,4295, 78, -4296,4297, 81,3196,3196,3196,3196,3196,3196,3196,3196, 90,3196,4298, 93,4299, -3196,3196,3196,3196,3196,3196,3196,4300,3196,3196,3196,3196,3196,3196,3196,3196, -3196,3196,3196,3196,3196,4101,3196,4301,3196,3196,3196,3196,3196,3196,3196,3196, -3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196, -3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196, -3196,3196,3196,4302,4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313, -4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,3196,3196,4326, 154, -4327,4328,4329,3196,3196, 160,3196,3196,3196,4330,4331,4332,4333,4334,4335,3196, -3196,4336, 160,4337,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196, -3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196, -3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196, +3415,4395,3324,3324,4396,3324,3324,3324,3324,3324,3324, 378,3324,3324,3822,3324, +3324,4397,3324,4398,4399,4400,3324,3324,3324, 370,3324,4401,4402,4403,4404,4405, +3324,4406,4407,4408,3438,3438,4409, 442,4410,3324,3324,4411,4412,4411, 676,4413, +4414,3324,3324,4415, 51,3324,3324,3324,4416,3452,4417,3324, 59,4418,4416, 62, +3324,4419,4419,4420, 67,3324, 664,4421,3324,2316,3324,4422, 70,3324,4423, 78, +4424,4425, 81,3324,3324,3324,3324,3324,3324,3324,3324, 90,3324,4426, 93,4427, +3324,3324,3324,3324,3324,3324,3324,4428,3324,3324,3324,3324,3324,3324,3324,3324, +3324,3324,3324,3324,3324,4229,3324,4429,3324,3324,3324,3324,3324,3324,3324,3324, +3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324, +3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324, +3324,3324,3324,4430,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441, +4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,3324,3324,4454, 154, +4455,4456,4457,3324,3324, 160,3324,3324,3324,4458,4459,4460,4461,4462,4463,3324, +3324,4464, 160,4465,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324, +3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324, +3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324, }, { -3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815, -3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831, -3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847, -3840,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862, -3863,3864,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877, -3878,3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893, -3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909, -3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,4338,3921,3922,3923,3924,3925, -3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976, -3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3977,3977,3977,3977,3977, -3977,3977,3977,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939, -3940,3941,3942,3660,3943,3944,3662,3945,3663,3946,3947,3665,3948,3949,3950,3951, -3952,3953,3954,3955,3956,3936,3676,3957,3958,3679,3959,3960,3961,3962,3684,3685, -3963,3964,3965,3977,3977,3977,3977,3977,3977,3976,3985,3985,3985,3985,3985,3985, -3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985, -3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985, +3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943, +3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959, +3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975, +3968,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990, +3991,3992,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005, +4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021, +4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037, +4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4466,4049,4050,4051,4052,4053, +4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104, +4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4105,4105,4105,4105,4105, +4105,4105,4105,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067, +4068,4069,4070,3788,4071,4072,3790,4073,3791,4074,4075,3793,4076,4077,4078,4079, +4080,4081,4082,4083,4084,4064,3804,4085,4086,3807,4087,4088,4089,4090,3812,3813, +4091,4092,4093,4105,4105,4105,4105,4105,4105,4104,4113,4113,4113,4113,4113,4113, +4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113, +4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113, }, { -4339,4340,4341,4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354, -4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370, -4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386, -4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402, -4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418, -4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434, -4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450, -4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,4467,4468,4469,4470,4471, -4472,4473,4474,4475,4476,4477,4217,4478,4218,4479,4480,4481,4482,4483,4221,4484, -4485,4222,4486,4487,4224,4488,4489,4226,4490,4227,4491,4492,4493,4494,4495,4496, -4497,4498,4499,4500,4501, 320,4502,4503,4504,4505,4506,4507,4508,1374,4509,4510, -4511,4512,4513,4514,4515,4516,4517,4518, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, +4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481,4482, +4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497,4498, +4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514, +4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530, +4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546, +4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562, +4563,4564,4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578, +4579,4580,4581,4582,4583,4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,4595,4596,4597,4598,4599, +4600,4601,4602,4603,4604,4605,4345,4606,4346,4607,4608,4609,4610,4611,4349,4612, +4613,4614,4615,4616,4352,4617,4618,4354,4619,4620,4621,4622,4623,4624,4625,4626, +4627,4628,4629,4630,4631, 320,4632,4633,4634,4635,4636,4637,4638,1374,4639,4640, +4641,4642,4643,4644,4645,4646,4647,4648, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -4519,4520,4521,4522,4520,4523,4524,4525,4526,4527,4528,4530,4531,4532,4533,4534, -4535,4537,4539,4532,4541,4542,4543,4544,4545,4546,4547, 295, 28, 29, 30, 31, +4649,4650,4651,4652,4650,4653,4654,4655,4656,4657,4658,4660,4661,4662,4663,4664, +4665,4667,4669,4662,4671,4672,4673,4674,4675,4676,4677, 295, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 33, 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, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, @@ -10638,30 +10771,30 @@ const unsigned short banks[75][256] = 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 127,4536, 128,4538, 130, 131, 132,4540, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144,4529, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 295, 295, 295, 127,4666, 128,4668, 130, 131, 132,4670, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144,4659, 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, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, { -4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,3295,4558,4562, -3298,4563,4564,3298,4565,4566,4566,4566, 868, 869, 870,4567,4568,4569,4570,4571, -4572,4573,4574,4574,4575,4572,4576,4577,3842,4578,4579,4579,4580,4581,4582,4583, -4584,4585,4586,4586,4587,4096,3322,4588,4589,4590,4591,4592,4593,4589,4589,4594, -3329, 769,3330,3331,4595,4596,4597,4598,4599,4600,4601,4602,4603,4600,1300,4604, -4605,4606,4600,4565,4607,4589,4608,4609,3347,4610,4611,4612,4613,1314,4614,4615, -4616,4617,4618,4611,4611,1322,4619,4620,4621,4622,4623,4622,3295,4624,3842,4625, -4626,1334,4626,4627,4628,4629, 792,4630,1341,1342,1343,1344,4631,4632,4633,1348, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806,4634,4634,4635,4636,4635,4637,4638,4639,4640,4641,4642,4643,4644, -4645,4646,4647,4648,4649,4650,4651,4652,4653,4646,4654,4655,4656,4657,4658,4659, -4660,4661,4662,4663,4664,4665,4666,4663,4664,4665,4667,4668,4669,4670,1375,1371, -4671,4672, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, - 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, +4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,4689,4690,4691,3423,4688,4692, +3426,4693,4694,3426,4695,4696,4696,4696, 868, 869, 870,4697,4698,4699,4700,4701, +4702,4703,4704,4704,4705,4702,4706,4707,3970,4708,4709,4709,4710,4711,4712,4713, +4714,4715,4716,4716,4717,4224,3450,4718,4719,4720,4721,4722,4723,4719,4719,4724, +3457, 769,3458,3459,4725,4726,4727,4728,4729,4730,4731,4732,4733,4730,1300,4734, +4735,4736,4730,4695,4737,4719,4738,4739,3475,4740,4741,4742,4743,1314,4744,4745, +4746,4747,4748,4741,4741,1322,4749,4750,4751,4752,4753,4752,3423,4754,3970,4755, +4756,1334,4756,4757,4758,4759, 792,4760,1341,1342,1343,1344,4761,4762,4763,1348, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295,4764,4764,4765,4766,4765,4767,4768,4769,4770,4771,4772,4773,4774, +4775,4776,4777,4778,4779,4780,4781,4782,4783,4776,4784,4785,4786,4787,4788,4789, +4790,4791,4792,4793,4794,4795,4796,4793,4794,4795,4797,4798,4799,4800,1375, 295, +4801,4802, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, }, }; @@ -10741,5 +10874,5 @@ const AdlBankSetup adlbanksetup[75] = {3, 0, 0, 0, 0}, //Bank 71, TMB (Nam) {0, 0, 0, 0, 0}, //Bank 72, WOPL (DMXOPL3 bank by Sneakernets) {1, 0, 0, 0, 0}, //Bank 73, EA (Cartooners) - {0, 1, 0, 0, 0} //Bank 74, WOPL (Apogee IMF 90-ish) + {0, 0, 1, 0, 0} //Bank 74, WOPL (Apogee IMF 90-ish) }; diff --git a/src/adldata.hh b/src/adldata.hh index e9ff00b..104db82 100644 --- a/src/adldata.hh +++ b/src/adldata.hh @@ -24,8 +24,16 @@ #ifndef ADLDATA_H #define ADLDATA_H +#include <string.h> #include <stdint.h> +#pragma pack(push, 1) +#define ADLDATA_BYTE_COMPARABLE(T) \ + inline bool operator==(const T &a, const T &b) \ + { return !memcmp(&a, &b, sizeof(T)); } \ + inline bool operator!=(const T &a, const T &b) \ + { return !operator==(a, b); } + extern const struct adldata { uint32_t modulator_E862, carrier_E862; // See below @@ -34,22 +42,46 @@ extern const struct adldata int8_t finetune; } adl[]; +ADLDATA_BYTE_COMPARABLE(struct adldata) +enum { adlDefaultNumber = 189 }; extern const struct adlinsdata { - enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02 }; + enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02, Flag_Real4op = 0x04 }; uint16_t adlno1, adlno2; uint8_t tone; uint8_t flags; uint16_t ms_sound_kon; // Number of milliseconds it produces sound; uint16_t ms_sound_koff; - double voice2_fine_tune; + double voice2_fine_tune; } adlins[]; +ADLDATA_BYTE_COMPARABLE(struct adlinsdata) int maxAdlBanks(); extern const unsigned short banks[][256]; extern const char* const banknames[]; +enum { adlNoteOnMaxTime = 40000 }; + +/** + * @brief Instrument data with operators included + */ +struct adlinsdata2 +{ + adldata adl[2]; + uint8_t tone; + uint8_t flags; + uint16_t ms_sound_kon; // Number of milliseconds it produces sound; + uint16_t ms_sound_koff; + double voice2_fine_tune; + adlinsdata2() {} + explicit adlinsdata2(const adlinsdata &d); +}; +ADLDATA_BYTE_COMPARABLE(struct adlinsdata2) + +#undef ADLDATA_BYTE_COMPARABLE +#pragma pack(pop) + /** * @brief Bank global setup */ @@ -62,4 +94,26 @@ extern const struct AdlBankSetup bool scaleModulators; } adlbanksetup[]; +/** + * @brief Conversion of storage formats + */ +inline adlinsdata2::adlinsdata2(const adlinsdata &d) + : tone(d.tone), flags(d.flags), + ms_sound_kon(d.ms_sound_kon), ms_sound_koff(d.ms_sound_koff), + voice2_fine_tune(d.voice2_fine_tune) +{ + adl[0] = ::adl[d.adlno1]; + adl[1] = ::adl[d.adlno2]; +} + +/** + * @brief Convert external instrument to internal instrument + */ +void cvt_ADLI_to_FMIns(adlinsdata2 &dst, const struct ADL_Instrument &src); + +/** + * @brief Convert internal instrument to external instrument + */ +void cvt_FMIns_to_ADLI(struct ADL_Instrument &dst, const adlinsdata2 &src); + #endif //ADLDATA_H diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index bf03285..a0c7d8a 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -120,7 +120,7 @@ ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank) if(static_cast<uint32_t>(bankno) >= NumBanks) { char errBuf[150]; - snprintf(errBuf, 150, "Embedded bank number may only be 0..%" PRIu32 "!\n", (NumBanks - 1)); + snprintf(errBuf, 150, "Embedded bank number may only be 0..%u!\n", static_cast<unsigned int>(NumBanks - 1)); play->setErrorString(errBuf); return -1; } @@ -143,6 +143,142 @@ ADLMIDI_EXPORT const char *const *adl_getBankNames() return banknames; } +ADLMIDI_EXPORT int adl_reserveBanks(ADL_MIDIPlayer *device, unsigned banks) +{ + if(!device) + return -1; + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + OPL3::BankMap &map = play->opl.dynamic_banks; + map.reserve(banks); + return (int)map.capacity(); +} + +ADLMIDI_EXPORT int adl_getBank(ADL_MIDIPlayer *device, const ADL_BankId *idp, int flags, ADL_Bank *bank) +{ + if(!device || !idp || !bank) + return -1; + + ADL_BankId id = *idp; + if(id.lsb > 127 || id.msb > 127 || id.percussive > 1) + return -1; + unsigned idnumber = (id.msb << 8) | id.lsb | (id.percussive ? OPL3::PercussionTag : 0); + + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + OPL3::BankMap &map = play->opl.dynamic_banks; + + OPL3::BankMap::iterator it; + if(!(flags & ADLMIDI_Bank_Create)) + { + it = map.find(idnumber); + if(it == map.end()) + return -1; + } + else + { + std::pair<uint16_t, OPL3::Bank> value; + value.first = idnumber; + memset(&value.second, 0, sizeof(value.second)); + for (unsigned i = 0; i < 128; ++i) + value.second.ins[i].flags = adlinsdata::Flag_NoSound; + + std::pair<OPL3::BankMap::iterator, bool> ir; + if(flags & ADLMIDI_Bank_CreateRt) + { + ir = map.insert(value, OPL3::BankMap::do_not_expand_t()); + if(ir.first == map.end()) + return -1; + } + else + ir = map.insert(value); + it = ir.first; + } + + it.to_ptrs(bank->pointer); + return 0; +} + +ADLMIDI_EXPORT int adl_getBankId(ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id) +{ + if(!device || !bank) + return -1; + + OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer); + unsigned idnumber = it->first; + id->msb = (idnumber >> 8) & 127; + id->lsb = idnumber & 127; + id->percussive = (idnumber & OPL3::PercussionTag) ? 1 : 0; + return 0; +} + +ADLMIDI_EXPORT int adl_removeBank(ADL_MIDIPlayer *device, ADL_Bank *bank) +{ + if(!device || !bank) + return -1; + + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + OPL3::BankMap &map = play->opl.dynamic_banks; + OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer); + size_t size = map.size(); + map.erase(it); + return (map.size() != size) ? 0 : -1; +} + +ADLMIDI_EXPORT int adl_getFirstBank(ADL_MIDIPlayer *device, ADL_Bank *bank) +{ + if(!device) + return -1; + + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + OPL3::BankMap &map = play->opl.dynamic_banks; + + OPL3::BankMap::iterator it = map.begin(); + if(it == map.end()) + return -1; + + it.to_ptrs(bank->pointer); + return 0; +} + +ADLMIDI_EXPORT int adl_getNextBank(ADL_MIDIPlayer *device, ADL_Bank *bank) +{ + if(!device) + return -1; + + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + OPL3::BankMap &map = play->opl.dynamic_banks; + + OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer); + if(++it == map.end()) + return -1; + + it.to_ptrs(bank->pointer); + return 0; +} + +ADLMIDI_EXPORT int adl_getInstrument(ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins) +{ + if(!device || !bank || index > 127 || !ins) + return 1; + + OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer); + cvt_FMIns_to_ADLI(*ins, it->second.ins[index]); + ins->version = 0; + return 0; +} + +ADLMIDI_EXPORT int adl_setInstrument(ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins) +{ + if(!device || !bank || index > 127 || !ins) + return 1; + + if(ins->version != 0) + return 1; + + OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer); + cvt_ADLI_to_FMIns(it->second.ins[index], *ins); + return 0; +} + ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) { if(!device) @@ -177,7 +313,9 @@ ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.AdlPercussionMode = percmod; - play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode; + play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode < 0 ? + play->opl.dynamic_bank_setup.adLibPercussions : + (play->m_setup.AdlPercussionMode != 0); play->opl.updateFlags(); } @@ -186,7 +324,9 @@ ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.HighVibratoMode = hvibro; - play->opl.HighVibratoMode = play->m_setup.HighVibratoMode; + play->opl.HighVibratoMode = play->m_setup.HighVibratoMode < 0 ? + play->opl.dynamic_bank_setup.deepVibrato : + (play->m_setup.HighVibratoMode != 0); play->opl.updateDeepFlags(); } @@ -195,7 +335,9 @@ ADLMIDI_EXPORT void adl_setHTremolo(ADL_MIDIPlayer *device, int htremo) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.HighTremoloMode = htremo; - play->opl.HighTremoloMode = play->m_setup.HighTremoloMode; + play->opl.HighTremoloMode = play->m_setup.HighTremoloMode < 0 ? + play->opl.dynamic_bank_setup.deepTremolo : + (play->m_setup.HighTremoloMode != 0); play->opl.updateDeepFlags(); } @@ -204,14 +346,16 @@ ADLMIDI_EXPORT void adl_setScaleModulators(ADL_MIDIPlayer *device, int smod) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.ScaleModulators = smod; - play->opl.ScaleModulators = play->m_setup.ScaleModulators; + play->opl.ScaleModulators = play->m_setup.ScaleModulators < 0 ? + play->opl.dynamic_bank_setup.scaleModulators : + (play->m_setup.ScaleModulators != 0); } ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness) { if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); - play->m_setup.fullRangeBrightnessCC74 = fr_brightness; + play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0); } ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn) @@ -221,12 +365,16 @@ ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn) play->m_setup.loopingIsEnabled = (loopEn != 0); } +/* !!!DEPRECATED!!! */ ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol) { if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); - play->m_setup.LogarithmicVolumes = logvol; - play->opl.LogarithmicVolumes = play->m_setup.LogarithmicVolumes; + play->m_setup.LogarithmicVolumes = (logvol != 0); + if(play->m_setup.LogarithmicVolumes) + play->opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); + else + play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(play->opl.m_volumeScale)); } ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel) @@ -234,7 +382,10 @@ ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int v if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.VolumeModel = volumeModel; - play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel)); + if(play->m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model + play->opl.m_volumeScale = (OPL3::VolumesScale)play->opl.dynamic_bank_setup.volumeModel; + else + play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel)); } ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath) @@ -367,7 +518,11 @@ ADLMIDI_EXPORT int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulato ADLMIDI_EXPORT const char *adl_linkedLibraryVersion() { +#if !defined(ADLMIDI_ENABLE_HQ_RESAMPLER) return ADLMIDI_VERSION; +#else + return ADLMIDI_VERSION " (HQ)"; +#endif } ADLMIDI_EXPORT const ADL_Version *adl_linkedVersion() @@ -421,7 +576,7 @@ ADLMIDI_EXPORT void adl_reset(struct ADL_MIDIPlayer *device) play->m_setup.tick_skip_samples_delay = 0; play->opl.Reset(play->m_setup.emulator, play->m_setup.PCM_RATE); play->ch.clear(); - play->ch.resize(play->opl.NumChannels); + play->ch.resize((size_t)play->opl.NumChannels); } ADLMIDI_EXPORT double adl_totalTimeLength(struct ADL_MIDIPlayer *device) @@ -614,7 +769,7 @@ ADLMIDI_EXPORT void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_D play->hooks.onDebugMessage_userData = userData; } - +#ifndef ADLMIDI_HW_OPL template <class Dst> static void CopySamplesRaw(ADL_UInt8 *dstLeft, ADL_UInt8 *dstRight, const int32_t *src, size_t frameCount, unsigned sampleOffset) @@ -659,6 +814,8 @@ static int SendStereoAudio(int samples_requested, right += (outputOffset / 2) * sampleOffset; typedef int32_t(&pfnConvert)(int32_t); + typedef float(&ffnConvert)(int32_t); + typedef double(&dfnConvert)(int32_t); switch(sampleType) { case ADLMIDI_SampleType_S8: @@ -723,22 +880,28 @@ static int SendStereoAudio(int samples_requested, break; } case ADLMIDI_SampleType_F32: + { if(containerSize != sizeof(float)) return -1; - CopySamplesTransformed<float>(left, right, _in, toCopy / 2, sampleOffset, adl_cvtReal<float>); + ffnConvert cvt = adl_cvtReal<float>; + CopySamplesTransformed<float>(left, right, _in, toCopy / 2, sampleOffset, cvt); break; + } case ADLMIDI_SampleType_F64: + { if(containerSize != sizeof(double)) return -1; - CopySamplesTransformed<double>(left, right, _in, toCopy / 2, sampleOffset, adl_cvtReal<double>); + dfnConvert cvt = adl_cvtReal<double>; + CopySamplesTransformed<double>(left, right, _in, toCopy / 2, sampleOffset, cvt); break; + } default: return -1; } return 0; } - +#endif ADLMIDI_EXPORT int adl_play(struct ADL_MIDIPlayer *device, int sampleCount, short *out) { diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h new file mode 100644 index 0000000..e4534cd --- /dev/null +++ b/src/adlmidi_bankmap.h @@ -0,0 +1,127 @@ +/* + * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation + * + * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> + * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> + * + * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: + * http://iki.fi/bisqwit/source/adlmidi.html + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ADLMIDI_BANKMAP_H +#define ADLMIDI_BANKMAP_H + +#include <list> +#include <utility> +#include <stdint.h> +#include <stddef.h> + +#include "adlmidi_ptr.hpp" + +/** + * A simple hash map which accepts bank numbers as keys, can be reserved to a + * fixed size, offers O(1) search and insertion, has a hash function to + * optimize for the worst case, and has some good cache locality properties. + */ +template <class T> +class BasicBankMap +{ +public: + typedef uint16_t key_type; /* the bank identifier */ + typedef T mapped_type; + typedef std::pair<key_type, T> value_type; + + BasicBankMap(); + void reserve(size_t capacity); + + size_t size() const + { return m_size; } + size_t capacity() const + { return m_capacity; } + bool empty() const + { return m_size == 0; } + + class iterator; + iterator begin() const; + iterator end() const; + + struct do_not_expand_t {}; + + iterator find(key_type key); + void erase(iterator it); + std::pair<iterator, bool> insert(const value_type &value); + std::pair<iterator, bool> insert(const value_type &value, do_not_expand_t); + void clear(); + + T &operator[](key_type key); + +private: + struct Slot; + enum { minimum_allocation = 4 }; + enum + { + hash_bits = 8, /* worst case # of collisions: 128^2/2^hash_bits */ + hash_buckets = 1 << hash_bits, + }; + +public: + class iterator + { + public: + iterator(); + value_type &operator*() const { return slot->value; } + value_type *operator->() const { return &slot->value; } + iterator &operator++(); + bool operator==(const iterator &o) const; + bool operator!=(const iterator &o) const; + void to_ptrs(void *ptrs[3]); + static iterator from_ptrs(void *const ptrs[3]); + private: + Slot **buckets; + Slot *slot; + size_t index; + iterator(Slot **buckets, Slot *slot, size_t index); +#ifdef _MSC_VER + template<class _T> + friend class BasicBankMap; +#else + friend class BasicBankMap<T>; +#endif + }; + +private: + struct Slot { + Slot *next, *prev; + value_type value; + Slot() : next(NULL), prev(NULL) {} + }; + AdlMIDI_SPtrArray<Slot *> m_buckets; + std::list< AdlMIDI_SPtrArray<Slot> > m_allocations; + Slot *m_freeslots; + size_t m_size; + size_t m_capacity; + static size_t hash(key_type key); + Slot *allocate_slot(); + Slot *ensure_allocate_slot(); + void free_slot(Slot *slot); + Slot *bucket_find(size_t index, key_type key); + void bucket_add(size_t index, Slot *slot); + void bucket_remove(size_t index, Slot *slot); +}; + +#include "adlmidi_bankmap.tcc" + +#endif // ADLMIDI_BANKMAP_H diff --git a/src/adlmidi_bankmap.tcc b/src/adlmidi_bankmap.tcc new file mode 100644 index 0000000..76e7001 --- /dev/null +++ b/src/adlmidi_bankmap.tcc @@ -0,0 +1,283 @@ +/* + * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation + * + * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> + * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> + * + * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: + * http://iki.fi/bisqwit/source/adlmidi.html + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "adlmidi_bankmap.h" +#include <cassert> + +template <class T> +inline BasicBankMap<T>::BasicBankMap() + : m_freeslots(NULL), + m_size(0), + m_capacity(0) +{ + m_buckets.reset(new Slot *[hash_buckets]()); +} + +template <class T> +inline size_t BasicBankMap<T>::hash(key_type key) +{ + // disregard the 0 high bit in LSB + key = (key & 127) | ((key >> 8) << 7); + // take low part as hash value + return key & (hash_buckets - 1); +} + +template <class T> +void BasicBankMap<T>::reserve(size_t capacity) +{ + if(m_capacity >= capacity) + return; + + size_t need = capacity - m_capacity; + const size_t minalloc = static_cast<size_t>(minimum_allocation); + need = (need < minalloc) ? minalloc : need; + + AdlMIDI_SPtrArray<Slot> slotz; + slotz.reset(new Slot[need]); + m_allocations.push_back(slotz); + m_capacity += need; + + for(size_t i = need; i-- > 0;) + free_slot(&slotz[i]); +} + +template <class T> +typename BasicBankMap<T>::iterator +BasicBankMap<T>::begin() const +{ + iterator it(m_buckets.get(), NULL, 0); + while(it.index < hash_buckets && !(it.slot = m_buckets[it.index])) + ++it.index; + return it; +} + +template <class T> +typename BasicBankMap<T>::iterator +BasicBankMap<T>::end() const +{ + iterator it(m_buckets.get(), NULL, hash_buckets); + return it; +} + +template <class T> +typename BasicBankMap<T>::iterator BasicBankMap<T>::find(key_type key) +{ + size_t index = hash(key); + Slot *slot = bucket_find(index, key); + if(!slot) + return end(); + return iterator(m_buckets.get(), slot, index); +} + +template <class T> +void BasicBankMap<T>::erase(iterator it) +{ + bucket_remove(it.index, it.slot); + free_slot(it.slot); + --m_size; +} + +template <class T> +inline BasicBankMap<T>::iterator::iterator() + : buckets(NULL), slot(NULL), index(0) +{ +} + +template <class T> +inline BasicBankMap<T>::iterator::iterator(Slot **buckets, Slot *slot, size_t index) + : buckets(buckets), slot(slot), index(index) +{ +} + +template <class T> +typename BasicBankMap<T>::iterator & +BasicBankMap<T>::iterator::operator++() +{ + if(slot->next) + slot = slot->next; + else { + Slot *slot = NULL; + ++index; + while(index < hash_buckets && !(slot = buckets[index])) + ++index; + this->slot = slot; + } + return *this; +} + +template <class T> +bool BasicBankMap<T>::iterator::operator==(const iterator &o) const +{ + return buckets == o.buckets && slot == o.slot && index == o.index; +} + +template <class T> +inline bool BasicBankMap<T>::iterator::operator!=(const iterator &o) const +{ + return !operator==(o); +} + +template <class T> +void BasicBankMap<T>::iterator::to_ptrs(void *ptrs[3]) +{ + ptrs[0] = buckets; + ptrs[1] = slot; + ptrs[2] = (void *)index; +} + +template <class T> +typename BasicBankMap<T>::iterator +BasicBankMap<T>::iterator::from_ptrs(void *const ptrs[3]) +{ + iterator it; + it.buckets = (Slot **)ptrs[0]; + it.slot = (Slot *)ptrs[1]; + it.index = (size_t)ptrs[2]; + return it; +} + +template <class T> +std::pair<typename BasicBankMap<T>::iterator, bool> +BasicBankMap<T>::insert(const value_type &value) +{ + size_t index = hash(value.first); + Slot *slot = bucket_find(index, value.first); + if(slot) + return std::make_pair(iterator(m_buckets.get(), slot, index), false); + slot = allocate_slot(); + if(!slot) { + reserve(m_capacity + minimum_allocation); + slot = ensure_allocate_slot(); + } + slot->value = value; + bucket_add(index, slot); + ++m_size; + return std::make_pair(iterator(m_buckets.get(), slot, index), true); +} + +template <class T> +std::pair<typename BasicBankMap<T>::iterator, bool> +BasicBankMap<T>::insert(const value_type &value, do_not_expand_t) +{ + size_t index = hash(value.first); + Slot *slot = bucket_find(index, value.first); + if(slot) + return std::make_pair(iterator(m_buckets.get(), slot, index), false); + slot = allocate_slot(); + if(!slot) + return std::make_pair(end(), false); + slot->value = value; + bucket_add(index, slot); + ++m_size; + return std::make_pair(iterator(m_buckets.get(), slot, index), true); +} + +template <class T> +void BasicBankMap<T>::clear() +{ + for(size_t i = 0; i < hash_buckets; ++i) { + Slot *slot = m_buckets[i]; + while (Slot *cur = slot) { + slot = slot->next; + free_slot(cur); + } + m_buckets[i] = NULL; + } + m_size = 0; +} + +template <class T> +inline T &BasicBankMap<T>::operator[](key_type key) +{ + return insert(value_type(key, T())).first->second; +} + +template <class T> +typename BasicBankMap<T>::Slot * +BasicBankMap<T>::allocate_slot() +{ + Slot *slot = m_freeslots; + if(!slot) + return NULL; + Slot *next = slot->next; + if(next) + next->prev = NULL; + m_freeslots = next; + return slot; +} + +template <class T> +inline typename BasicBankMap<T>::Slot * +BasicBankMap<T>::ensure_allocate_slot() +{ + Slot *slot = allocate_slot(); + assert(slot); + return slot; +} + +template <class T> +void BasicBankMap<T>::free_slot(Slot *slot) +{ + Slot *next = m_freeslots; + if(next) + next->prev = slot; + slot->prev = NULL; + slot->next = next; + m_freeslots = slot; + m_freeslots->value.second = T(); +} + +template <class T> +typename BasicBankMap<T>::Slot * +BasicBankMap<T>::bucket_find(size_t index, key_type key) +{ + Slot *slot = m_buckets[index]; + while(slot && slot->value.first != key) + slot = slot->next; + return slot; +} + +template <class T> +void BasicBankMap<T>::bucket_add(size_t index, Slot *slot) +{ + assert(slot); + Slot *next = m_buckets[index]; + if(next) + next->prev = slot; + slot->next = next; + m_buckets[index] = slot; +} + +template <class T> +void BasicBankMap<T>::bucket_remove(size_t index, Slot *slot) +{ + assert(slot); + Slot *prev = slot->prev; + Slot *next = slot->next; + if(!prev) + m_buckets[index] = next; + else + prev->next = next; + if(next) + next->prev = prev; +} diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index 703f34a..9e19ab6 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -72,65 +72,128 @@ bool MIDIplay::LoadBank(const void *data, size_t size) return LoadBank(file); } - -struct WOPL_Inst -{ - bool fourOps; - char padding[7]; - struct adlinsdata adlins; - struct adldata op[2]; - uint16_t ms_sound_kon; - uint16_t ms_sound_koff; -}; - -static void cvt_WOPLI_to_FMIns(WOPL_Inst &ins, WOPLInstrument &in) +template <class WOPLI> +static void cvt_generic_to_FMIns(adlinsdata2 &ins, const WOPLI &in) { - ins.op[0].finetune = in.note_offset1; - ins.op[1].finetune = in.note_offset2; - - ins.adlins.voice2_fine_tune = 0.0; + ins.voice2_fine_tune = 0.0; int8_t voice2_fine_tune = in.second_voice_detune; if(voice2_fine_tune != 0) { if(voice2_fine_tune == 1) - ins.adlins.voice2_fine_tune = 0.000025; + ins.voice2_fine_tune = 0.000025; else if(voice2_fine_tune == -1) - ins.adlins.voice2_fine_tune = -0.000025; + ins.voice2_fine_tune = -0.000025; else - ins.adlins.voice2_fine_tune = ((voice2_fine_tune * 15.625) / 1000.0); + ins.voice2_fine_tune = voice2_fine_tune * (15.625 / 1000.0); } - ins.adlins.tone = in.percussion_key_number; + ins.tone = in.percussion_key_number; + ins.flags = (in.inst_flags & WOPL_Ins_4op) && (in.inst_flags & WOPL_Ins_Pseudo4op) ? adlinsdata::Flag_Pseudo4op : 0; + ins.flags|= (in.inst_flags & WOPL_Ins_4op) && ((in.inst_flags & WOPL_Ins_Pseudo4op) == 0) ? adlinsdata::Flag_Real4op : 0; + ins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0; - ins.adlins.flags = (in.inst_flags & WOPL_Ins_4op) && (in.inst_flags & WOPL_Ins_Pseudo4op) ? adlinsdata::Flag_Pseudo4op : 0; - ins.adlins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0; - ins.fourOps = (in.inst_flags & WOPL_Ins_4op) || (in.inst_flags & WOPL_Ins_Pseudo4op); - - ins.op[0].feedconn = in.fb_conn1_C0; - ins.op[1].feedconn = in.fb_conn2_C0; - - for(size_t op = 0, slt = 0; op < 4; op++, slt++) + bool fourOps = (in.inst_flags & WOPL_Ins_4op) || (in.inst_flags & WOPL_Ins_Pseudo4op); + for(size_t op = 0, slt = 0; op < static_cast<size_t>(fourOps ? 4 : 2); op++, slt++) { - ins.op[slt].carrier_E862 = + ins.adl[slt].carrier_E862 = ((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm | ((static_cast<uint32_t>(in.operators[op].susrel_80) << 16) & 0x00FF0000) //SusRel | ((static_cast<uint32_t>(in.operators[op].atdec_60) << 8) & 0x0000FF00) //AtDec | ((static_cast<uint32_t>(in.operators[op].avekf_20) << 0) & 0x000000FF); //AVEKM - ins.op[slt].carrier_40 = in.operators[op].ksl_l_40;//KSLL + ins.adl[slt].carrier_40 = in.operators[op].ksl_l_40;//KSLL op++; - ins.op[slt].modulator_E862 = + ins.adl[slt].modulator_E862 = ((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm | ((static_cast<uint32_t>(in.operators[op].susrel_80) << 16) & 0x00FF0000) //SusRel | ((static_cast<uint32_t>(in.operators[op].atdec_60) << 8) & 0x0000FF00) //AtDec | ((static_cast<uint32_t>(in.operators[op].avekf_20) << 0) & 0x000000FF); //AVEKM - ins.op[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL + ins.adl[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL + } + + ins.adl[0].finetune = static_cast<int8_t>(in.note_offset1); + ins.adl[0].feedconn = in.fb_conn1_C0; + if(!fourOps) + ins.adl[1] = ins.adl[0]; + else + { + ins.adl[1].finetune = static_cast<int8_t>(in.note_offset2); + ins.adl[1].feedconn = in.fb_conn2_C0; } ins.ms_sound_kon = in.delay_on_ms; ins.ms_sound_koff = in.delay_off_ms; } +template <class WOPLI> +static void cvt_FMIns_to_generic(WOPLI &ins, const adlinsdata2 &in) +{ + ins.second_voice_detune = 0; + double voice2_fine_tune = in.voice2_fine_tune; + if(voice2_fine_tune != 0) + { + if(voice2_fine_tune > 0 && voice2_fine_tune <= 0.000025) + ins.second_voice_detune = 1; + else if(voice2_fine_tune < 0 && voice2_fine_tune >= -0.000025) + ins.second_voice_detune = -1; + else + { + long value = lround(voice2_fine_tune * (1000.0 / 15.625)); + value = (value < -128) ? -128 : value; + value = (value > +127) ? +127 : value; + ins.second_voice_detune = static_cast<int8_t>(value); + } + } + + ins.percussion_key_number = in.tone; + bool fourOps = (in.flags & adlinsdata::Flag_Pseudo4op) || in.adl[0] != in.adl[1]; + ins.inst_flags = fourOps ? WOPL_Ins_4op : 0; + ins.inst_flags|= (in.flags & adlinsdata::Flag_Pseudo4op) ? WOPL_Ins_Pseudo4op : 0; + ins.inst_flags|= (in.flags & adlinsdata::Flag_NoSound) ? WOPL_Ins_IsBlank : 0; + + for(size_t op = 0, slt = 0; op < static_cast<size_t>(fourOps ? 4 : 2); op++, slt++) + { + ins.operators[op].waveform_E0 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 24); + ins.operators[op].susrel_80 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 16); + ins.operators[op].atdec_60 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 8); + ins.operators[op].avekf_20 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 0); + ins.operators[op].ksl_l_40 = in.adl[slt].carrier_40; + + op++; + ins.operators[op].waveform_E0 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 24); + ins.operators[op].susrel_80 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 16); + ins.operators[op].atdec_60 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 8); + ins.operators[op].avekf_20 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 0); + ins.operators[op].ksl_l_40 = in.adl[slt].carrier_40; + } + + ins.note_offset1 = in.adl[0].finetune; + ins.fb_conn1_C0 = in.adl[0].feedconn; + if(!fourOps) + { + ins.operators[2] = ins.operators[0]; + ins.operators[3] = ins.operators[1]; + } + else + { + ins.note_offset2 = in.adl[1].finetune; + ins.fb_conn2_C0 = in.adl[1].feedconn; + } + + ins.delay_on_ms = in.ms_sound_kon; + ins.delay_off_ms = in.ms_sound_koff; +} + +void cvt_ADLI_to_FMIns(adlinsdata2 &ins, const ADL_Instrument &in) +{ + return cvt_generic_to_FMIns(ins, in); +} + +void cvt_FMIns_to_ADLI(ADL_Instrument &ins, const adlinsdata2 &in) +{ + cvt_FMIns_to_generic(ins, in); +} + bool MIDIplay::LoadBank(MIDIplay::fileReader &fr) { int err = 0; @@ -187,54 +250,41 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr) } } - m_setup.HighTremoloMode = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0; - m_setup.HighVibratoMode = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0; - m_setup.VolumeModel = wopl->volume_model; - - /* TODO: Avoid memory reallocation in nearest future! */ - opl.dynamic_melodic_banks.clear(); - opl.dynamic_percussion_banks.clear(); + opl.dynamic_bank_setup.adLibPercussions = false; + opl.dynamic_bank_setup.scaleModulators = false; + opl.dynamic_bank_setup.deepTremolo = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0; + opl.dynamic_bank_setup.deepVibrato = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0; + opl.dynamic_bank_setup.volumeModel = wopl->volume_model; + m_setup.HighTremoloMode = -1; + m_setup.HighVibratoMode = -1; + m_setup.VolumeModel = ADLMIDI_VolumeModel_AUTO; opl.setEmbeddedBank(m_setup.AdlBank); - OPL3::BankMap *slots_banks[2] = { &opl.dynamic_melodic_banks, &opl.dynamic_percussion_banks}; uint16_t slots_counts[2] = {wopl->banks_count_melodic, wopl->banks_count_percussion}; WOPLBank *slots_src_ins[2] = { wopl->banks_melodic, wopl->banks_percussive }; - for(int ss = 0; ss < 2; ss++) + for(unsigned ss = 0; ss < 2; ss++) { - for(int i = 0; i < slots_counts[ss]; i++) + for(unsigned i = 0; i < slots_counts[ss]; i++) { - uint16_t bank = (slots_src_ins[ss][i].bank_midi_msb * 256) + slots_src_ins[ss][i].bank_midi_lsb; - size_t offset = slots_banks[ss]->size(); - (*slots_banks[ss])[bank] = offset; - + unsigned bankno = + (slots_src_ins[ss][i].bank_midi_msb * 256) + + slots_src_ins[ss][i].bank_midi_lsb + + (ss ? OPL3::PercussionTag : 0); + OPL3::Bank &bank = opl.dynamic_banks[bankno]; for(int j = 0; j < 128; j++) { - WOPL_Inst ins; - std::memset(&ins, 0, sizeof(WOPL_Inst)); + adlinsdata2 &ins = bank.ins[j]; + std::memset(&ins, 0, sizeof(adlinsdata2)); WOPLInstrument &inIns = slots_src_ins[ss][i].ins[j]; - - cvt_WOPLI_to_FMIns(ins, inIns); - - ins.adlins.ms_sound_kon = ins.ms_sound_kon; - ins.adlins.ms_sound_koff = ins.ms_sound_koff; - ins.adlins.adlno1 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag); - opl.dynamic_instruments.push_back(ins.op[0]); - ins.adlins.adlno2 = ins.adlins.adlno1; - if(ins.fourOps) - { - ins.adlins.adlno2 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag); - opl.dynamic_instruments.push_back(ins.op[1]); - } - opl.dynamic_metainstruments.push_back(ins.adlins); + cvt_generic_to_FMIns(ins, inIns); } } } opl.AdlBank = ~0u; // Use dynamic banks! //Percussion offset is count of instruments multipled to count of melodic banks - opl.dynamic_percussion_offset = 128 * wopl->banks_count_melodic; applySetup(); WOPL_Free(wopl); @@ -268,7 +318,7 @@ bool MIDIplay::LoadMIDI(MIDIplay::fileReader &fr) errorString.clear(); #ifdef DISABLE_EMBEDDED_BANKS - if((opl.AdlBank != ~0u) || (opl.dynamic_metainstruments.size() < 256)) + if((opl.AdlBank != ~0u) || opl.dynamic_banks.empty()) { errorStringOut = "Bank is not set! Please load any instruments bank by using of adl_openBankFile() or adl_openBankData() functions!"; return false; @@ -392,8 +442,7 @@ riffskip: #endif //ADLMIDI_DISABLE_XMI_SUPPORT else if(std::memcmp(HeaderBuf, "CTMF", 4) == 0) { - opl.dynamic_instruments.clear(); - opl.dynamic_metainstruments.clear(); + opl.dynamic_banks.clear(); // Creative Music Format (CMF). // When playing CTMF files, use the following commandline: // adlmidi song8.ctmf -p -v 1 1 0 @@ -415,13 +464,19 @@ riffskip: //std::printf("%u instruments\n", ins_count); for(unsigned i = 0; i < ins_count; ++i) { + unsigned bank = i / 256; + bank = (bank & 127) + ((bank >> 7) << 8); + if(bank > 127 + (127 << 8)) + break; + bank += (i % 256 < 128) ? 0 : OPL3::PercussionTag; + unsigned char InsData[16]; fr.read(InsData, 1, 16); /*std::printf("Ins %3u: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", i, InsData[0],InsData[1],InsData[2],InsData[3], InsData[4],InsData[5],InsData[6],InsData[7], InsData[8],InsData[9],InsData[10],InsData[11], InsData[12],InsData[13],InsData[14],InsData[15]);*/ - struct adldata adl; - struct adlinsdata adlins; + adlinsdata2 &adlins = opl.dynamic_banks[bank].ins[i % 128]; + adldata adl; adl.modulator_E862 = ((static_cast<uint32_t>(InsData[8] & 0x07) << 24) & 0xFF000000) //WaveForm | ((static_cast<uint32_t>(InsData[6]) << 16) & 0x00FF0000) //Sustain/Release @@ -436,15 +491,13 @@ riffskip: adl.carrier_40 = InsData[3]; adl.feedconn = InsData[10] & 0x0F; adl.finetune = 0; - adlins.adlno1 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag); - adlins.adlno2 = adlins.adlno1; + adlins.adl[0] = adl; + adlins.adl[1] = adl; adlins.ms_sound_kon = 1000; adlins.ms_sound_koff = 500; adlins.tone = 0; adlins.flags = 0; adlins.voice2_fine_tune = 0.0; - opl.dynamic_metainstruments.push_back(adlins); - opl.dynamic_instruments.push_back(adl); } fr.seeku(mus_start, SEEK_SET); @@ -452,10 +505,9 @@ riffskip: DeltaTicks = (size_t)ticks; opl.AdlBank = ~0u; // Ignore AdlBank number, use dynamic banks instead //std::printf("CMF deltas %u ticks %u, basictempo = %u\n", deltas, ticks, basictempo); - opl.LogarithmicVolumes = true; opl.AdlPercussionMode = true; opl.m_musicMode = OPL3::MODE_CMF; - opl.m_volumeScale = OPL3::VOLUME_CMF; + opl.m_volumeScale = OPL3::VOLUME_NATIVE; } else { @@ -470,10 +522,9 @@ riffskip: fr.seek(0x7D, SEEK_SET); TrackCount = 1; DeltaTicks = 60; - opl.LogarithmicVolumes = true; //opl.CartoonersVolumes = true; opl.m_musicMode = OPL3::MODE_RSXX; - opl.m_volumeScale = OPL3::VOLUME_CMF; + opl.m_volumeScale = OPL3::VOLUME_NATIVE; } } @@ -531,11 +582,11 @@ riffskip: TrackData.clear(); TrackData.resize(TrackCount, std::vector<uint8_t>()); - //CurrentPosition.track.clear(); - //CurrentPosition.track.resize(TrackCount); InvDeltaTicks = fraction<uint64_t>(1, 1000000l * static_cast<uint64_t>(DeltaTicks)); - //Tempo = 1000000l * InvDeltaTicks; - Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks)); + if(is_CMF || is_RSXX) + Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks)); + else + Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks) * 2); static const unsigned char EndTag[4] = {0xFF, 0x2F, 0x00, 0x00}; size_t totalGotten = 0; diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 7c40fa0..0623ce7 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -25,7 +25,7 @@ // Mapping from MIDI volume level to OPL level value. -static const uint32_t DMX_volume_mapping_table[] = +static const uint8_t DMX_volume_mapping_table[128] = { 0, 1, 3, 5, 6, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, @@ -43,23 +43,6 @@ static const uint32_t DMX_volume_mapping_table[] = 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127, - //Protection entries to avoid crash if value more than 127 - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, }; static const uint8_t W9X_volume_mapping_table[32] = @@ -117,17 +100,16 @@ inline bool isXgPercChannel(uint8_t msb, uint8_t lsb) void MIDIplay::AdlChannel::AddAge(int64_t ms) { + const int64_t neg = static_cast<int64_t>(-0x1FFFFFFFl); if(users_empty()) - koff_time_until_neglible = - std::max(int64_t(koff_time_until_neglible - ms), static_cast<int64_t>(-0x1FFFFFFFl)); + koff_time_until_neglible = std::max(int64_t(koff_time_until_neglible - ms), neg); else { koff_time_until_neglible = 0; - for(LocationData *i = users_first; i; i = i->next) { - i->kon_time_until_neglible = - std::max(i->kon_time_until_neglible - ms, static_cast<int64_t>(-0x1FFFFFFFl)); + if(!i->fixed_sustain) + i->kon_time_until_neglible = std::max(i->kon_time_until_neglible - ms, neg); i->vibdelay += ms; } } @@ -222,7 +204,9 @@ void MIDIplay::MidiTrackRow::sortEvents(bool *noteStates) j = noteOffs.erase(j); markAsOn.erase(note_i); continue; - } else { + } + else + { //When same row has many note-offs on same row //that means a zero-length note follows previous note //it must be shuted down @@ -451,17 +435,17 @@ bool MIDIplay::buildTrackData() if(track.empty()) continue;//Empty track is useless! - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, "\n============Track %" PRIuPTR "=============\n", tk); std::fflush(stdout); - #endif +#endif MidiTrackRow *posPrev = &(*(track.begin()));//First element for(MidiTrackQueue::iterator it = track.begin(); it != track.end(); it++) { - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION bool tempoChanged = false; - #endif +#endif MidiTrackRow &pos = *it; if((posPrev != &pos) && //Skip first event (!tempos.empty()) && //Only when in-track tempo events are available @@ -507,9 +491,9 @@ bool MIDIplay::buildTrackData() //Apply next tempo currentTempo = points[j].tempo; - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION tempoChanged = true; - #endif +#endif } //Then calculate time between last tempo change point and end point TempoChangePoint tailTempo = points.back(); @@ -552,10 +536,10 @@ bool MIDIplay::buildTrackData() loopEndTime = pos.time; } - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, "= %10" PRId64 " = %10f%s\n", pos.absPos, pos.time, tempoChanged ? " <----TEMPO CHANGED" : ""); std::fflush(stdout); - #endif +#endif abs_position += pos.delay; posPrev = &pos; @@ -575,7 +559,7 @@ bool MIDIplay::buildTrackData() //Resolve "hell of all times" of too short drum notes: //move too short percussion note-offs far far away as possible /********************************************************************************/ - #if 1 //Use this to record WAVEs for comparison before/after implementing of this +#if 1 //Use this to record WAVEs for comparison before/after implementing of this if(opl.m_musicMode == OPL3::MODE_MIDI)//Percussion fix is needed for MIDI only, not for IMF/RSXX or CMF { //! Minimal real time in seconds @@ -625,8 +609,8 @@ bool MIDIplay::buildTrackData() } bool percussion = (et->channel == 9) || - banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal) - banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal) + banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal) + banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal) if(!percussion) continue; @@ -687,7 +671,7 @@ bool MIDIplay::buildTrackData() #undef DRUM_NOTE_MIN_TIME #undef DRUM_NOTE_MIN_TICKS } - #endif +#endif return true; } @@ -695,7 +679,8 @@ bool MIDIplay::buildTrackData() MIDIplay::MIDIplay(unsigned long sampleRate): - cmf_percussion_mode(false) + cmf_percussion_mode(false), + m_arpeggioCounter(0) #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER , fullSongTimeLength(0.0), postSongWaitDelay(1.0), @@ -740,16 +725,28 @@ MIDIplay::MIDIplay(unsigned long sampleRate): void MIDIplay::applySetup() { m_setup.tick_skip_samples_delay = 0; - opl.HighTremoloMode = m_setup.HighTremoloMode == -1 ? adlbanksetup[m_setup.AdlBank].deepTremolo : (bool)m_setup.HighTremoloMode; - opl.HighVibratoMode = m_setup.HighVibratoMode == -1 ? adlbanksetup[m_setup.AdlBank].deepVibrato : (bool)m_setup.HighVibratoMode; - opl.AdlPercussionMode = m_setup.AdlPercussionMode == -1 ? adlbanksetup[m_setup.AdlBank].adLibPercussions : (bool)m_setup.AdlPercussionMode; - opl.ScaleModulators = m_setup.ScaleModulators == -1 ? adlbanksetup[m_setup.AdlBank].scaleModulators : (bool)m_setup.ScaleModulators; - opl.LogarithmicVolumes = m_setup.LogarithmicVolumes; - //opl.CartoonersVolumes = false; + + if(opl.AdlBank != ~0u) + opl.dynamic_bank_setup = adlbanksetup[m_setup.AdlBank]; + + opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ? + opl.dynamic_bank_setup.deepTremolo : + (m_setup.HighTremoloMode != 0); + opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ? + opl.dynamic_bank_setup.deepVibrato : + (m_setup.HighVibratoMode != 0); + opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ? + opl.dynamic_bank_setup.adLibPercussions : + (m_setup.AdlPercussionMode != 0); + opl.ScaleModulators = m_setup.ScaleModulators < 0 ? + opl.dynamic_bank_setup.scaleModulators : + (m_setup.ScaleModulators != 0); + if(m_setup.LogarithmicVolumes) + opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); opl.m_musicMode = OPL3::MODE_MIDI; opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(m_setup.VolumeModel)); if(m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model - opl.m_volumeScale = (OPL3::VolumesScale)adlbanksetup[m_setup.AdlBank].volumeModel; + opl.m_volumeScale = (OPL3::VolumesScale)opl.dynamic_bank_setup.volumeModel; opl.NumCards = m_setup.NumCards; opl.NumFourOps = m_setup.NumFourOps; @@ -758,6 +755,9 @@ void MIDIplay::applySetup() opl.Reset(m_setup.emulator, m_setup.PCM_RATE); ch.clear(); ch.resize(opl.NumChannels); + + // Reset the arpeggio counter + m_arpeggioCounter = 0; } #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER @@ -796,9 +796,9 @@ uint64_t MIDIplay::ReadVarLenEx(uint8_t **ptr, uint8_t *end, bool &ok) double MIDIplay::Tick(double s, double granularity) { s *= tempoMultiplier; - #ifdef ENABLE_BEGIN_SILENCE_SKIPPING +#ifdef ENABLE_BEGIN_SILENCE_SKIPPING if(CurrentPositionNew.began) - #endif +#endif CurrentPositionNew.wait -= s; CurrentPositionNew.absTimePosition += s; @@ -827,7 +827,7 @@ double MIDIplay::Tick(double s, double granularity) return CurrentPositionNew.wait; } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ void MIDIplay::TickIteratos(double s) { @@ -944,7 +944,7 @@ void MIDIplay::setTempo(double tempo) { tempoMultiplier = tempo; } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ void MIDIplay::realTime_ResetState() { @@ -964,6 +964,9 @@ void MIDIplay::realTime_ResetState() bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { + if(note >= 128) + note = 127; + if((opl.m_musicMode == OPL3::MODE_RSXX) && (velocity != 0)) { // Check if this is just a note after-touch @@ -986,14 +989,16 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(velocity == 0) return false; - size_t midiins = Ch[channel].patch; - bool isPercussion = (channel % 16 == 9); + MIDIchannel &midiChan = Ch[channel]; + + size_t midiins = midiChan.patch; + bool isPercussion = (channel % 16 == 9); bool isXgPercussion = false; uint16_t bank = 0; - if(Ch[channel].bank_msb || Ch[channel].bank_lsb) + if(midiChan.bank_msb || midiChan.bank_lsb) { - bank = (uint16_t(Ch[channel].bank_msb) * 256) + uint16_t(Ch[channel].bank_lsb); + bank = (uint16_t(midiChan.bank_msb) * 256) + uint16_t(midiChan.bank_lsb); //0x7E00 - XG SFX1/SFX2 channel (16128 signed decimal) //0x7F00 - XG Percussion channel (16256 signed decimal) if(bank == 0x7E00 || bank == 0x7F00) @@ -1001,7 +1006,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //Let XG SFX1/SFX2 bank will have LSB==1 (128...255 range in WOPN file) //Let XG Percussion bank will use (0...127 range in WOPN file) bank = (uint16_t)midiins + ((bank == 0x7E00) ? 128 : 0); // MIDI instrument defines the patch - midiins = opl.dynamic_percussion_offset + note; // Percussion instrument + midiins = note; // Percussion instrument isXgPercussion = true; isPercussion = false; } @@ -1010,43 +1015,43 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(isPercussion) { bank = (uint16_t)midiins; // MIDI instrument defines the patch - midiins = opl.dynamic_percussion_offset + note; // Percussion instrument + midiins = note; // Percussion instrument } + if(isPercussion || isXgPercussion) + bank += OPL3::PercussionTag; + + const adlinsdata2 *ains = &OPL3::emptyInstrument; //Set bank bank - if(bank > 0) + const OPL3::Bank *bnk = NULL; + if((bank & ~(uint16_t)OPL3::PercussionTag) > 0) { - if(isPercussion || isXgPercussion) - { - OPL3::BankMap::iterator b = opl.dynamic_percussion_banks.find(bank); - if(b != opl.dynamic_percussion_banks.end()) - midiins += b->second * 128; - else - if(hooks.onDebugMessage) - { - if(!caugh_missing_banks_melodic.count(bank)) - { - hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion MIDI bank %i (patch %i)", channel, bank, midiins); - caugh_missing_banks_melodic.insert(bank); - } - } - } - else + OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank); + if(b != opl.dynamic_banks.end()) + bnk = &b->second; + + if(bnk) + ains = &bnk->ins[midiins]; + else if(hooks.onDebugMessage) { - OPL3::BankMap::iterator b = opl.dynamic_melodic_banks.find(bank); - if(b != opl.dynamic_melodic_banks.end()) - midiins += b->second * 128; - else - if(hooks.onDebugMessage) - { - if(!caugh_missing_banks_percussion.count(bank)) - { - hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic MIDI bank %i (patch %i)", channel, bank, midiins); - caugh_missing_banks_percussion.insert(bank); - } - } + std::set<uint16_t> &missing = (isPercussion || isXgPercussion) ? + caugh_missing_banks_percussion : caugh_missing_banks_melodic; + const char *text = (isPercussion || isXgPercussion) ? + "percussion" : "melodic"; + if(missing.insert(bank).second) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing %s MIDI bank %i (patch %i)", channel, text, bank, midiins); } } + //Or fall back to first bank + if(ains->flags & adlinsdata::Flag_NoSound) + { + OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank & OPL3::PercussionTag); + if(b != opl.dynamic_banks.end()) + bnk = &b->second; + + if(bnk) + ains = &bnk->ins[midiins]; + } /* if(MidCh%16 == 9 || (midiins != 32 && midiins != 46 && midiins != 48 && midiins != 50)) @@ -1057,8 +1062,6 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //if(midiins == 56) vol = vol*6/10; // HACK //int meta = banks[opl.AdlBank][midiins]; - size_t meta = opl.GetAdlMetaNumber(midiins); - const adlinsdata *ains = &opl.GetAdlMetaIns(meta); int16_t tone = note; if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks @@ -1067,23 +1070,18 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { if(hooks.onDebugMessage) { - if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins))) - { + if(caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second) hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank); - caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)); - } } bank = 0; - midiins = Ch[channel].patch; - meta = opl.GetAdlMetaNumber(midiins); - ains = &opl.GetAdlMetaIns(meta); + midiins = midiChan.patch; } } if(ains->tone) { - /*if(ains.tone < 20) - tone += ains.tone; + /*if(ains->tone < 20) + tone += ains->tone; else*/ if(ains->tone < 128) tone = ains->tone; @@ -1091,24 +1089,32 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) tone -= ains->tone - 128; } - //uint16_t i[2] = { ains.adlno1, ains.adlno2 }; + //uint16_t i[2] = { ains->adlno1, ains->adlno2 }; bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op; +#ifndef __WATCOMC__ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] = { - {0, ains->adlno1, false}, - {0, ains->adlno2, pseudo_4op} + {0, ains->adl[0], false}, + {0, ains->adl[1], pseudo_4op} }; +#else /* Unfortunately, WatCom can't brace-initialize structure that incluses structure fields */ + MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans]; + voices[0].chip_chan = 0; + voices[0].ains = ains->adl[0]; + voices[0].pseudo4op = false; + voices[1].chip_chan = 0; + voices[1].ains = ains->adl[1]; + voices[1].pseudo4op = pseudo_4op; +#endif /* __WATCOMC__ */ if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) voices[1] = voices[0];//i[1] = i[0]; if(hooks.onDebugMessage) { - if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains->flags & adlinsdata::Flag_NoSound)) - { + if((ains->flags & adlinsdata::Flag_NoSound) && + caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second) hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins); - caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)); - } } // Allocate AdLib channel (the physical sound channel for the note) @@ -1132,7 +1138,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(ccount == 1 && static_cast<int32_t>(a) == adlchannel[0]) continue; // ^ Don't use the same channel for primary&secondary - if(voices[0].insId == voices[1].insId || pseudo_4op/*i[0] == i[1] || pseudo_4op*/) + if(voices[0].ains == voices[1].ains || pseudo_4op/*i[0] == i[1] || pseudo_4op*/) { // Only use regular channels uint8_t expected_mode = 0; @@ -1177,7 +1183,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "ignored unplaceable note [bank %i, inst %i, note %i, MIDI channel %i]", - bank, Ch[channel].patch, note, channel); + bank, midiChan.patch, note, channel); continue; // Could not play this note. Ignore it. } @@ -1196,11 +1202,12 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) // Allocate active note for MIDI channel std::pair<MIDIchannel::activenoteiterator, bool> - ir = Ch[channel].activenotes_insert(note); + ir = midiChan.activenotes_insert(note); ir.first->vol = velocity; + ir.first->vibrato = midiChan.noteAftertouch[note]; ir.first->tone = tone; ir.first->midiins = midiins; - ir.first->insmeta = meta; + ir.first->ains = ains; ir.first->chip_channels_count = 0; for(unsigned ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount) @@ -1224,29 +1231,28 @@ void MIDIplay::realTime_NoteOff(uint8_t channel, uint8_t note) void MIDIplay::realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t atVal) { channel = channel % 16; - MIDIchannel::activenoteiterator - i = Ch[channel].activenotes_find(note); - if(!i) + MIDIchannel &chan = Ch[channel]; + MIDIchannel::activenoteiterator i = Ch[channel].activenotes_find(note); + if(i) { - // Ignore touch if note is not active - return; + i->vibrato = atVal; + } + + uint8_t oldAtVal = chan.noteAftertouch[note % 128]; + if(atVal != oldAtVal) + { + chan.noteAftertouch[note % 128] = atVal; + bool inUse = atVal != 0; + for(unsigned n = 0; !inUse && n < 128; ++n) + inUse = chan.noteAftertouch[n] != 0; + chan.noteAfterTouchInUse = inUse; } - i->vol = 127 - atVal; - NoteUpdate(channel, i, Upd_Volume); } void MIDIplay::realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal) { - // TODO: Verify, is this correct action? channel = channel % 16; - for(MIDIchannel::activenoteiterator - i = Ch[channel].activenotes_begin(); i; ++i) - { - // Set this pressure to all active notes on the channel - i->vol = 127 - atVal; - } - - NoteUpdate_All(channel, Upd_Volume); + Ch[channel].aftertouch = atVal; } void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) @@ -1393,14 +1399,14 @@ void MIDIplay::realTime_PatchChange(uint8_t channel, uint8_t patch) void MIDIplay::realTime_PitchBend(uint8_t channel, uint16_t pitch) { channel = channel % 16; - Ch[channel].bend = (uint32_t(pitch) - 8192) * Ch[channel].bendsense; + Ch[channel].bend = int(pitch) - 8192; NoteUpdate_All(channel, Upd_Pitch); } void MIDIplay::realTime_PitchBend(uint8_t channel, uint8_t msb, uint8_t lsb) { channel = channel % 16; - Ch[channel].bend = (int(lsb) + int(msb) * 128 - 8192) * Ch[channel].bendsense; + Ch[channel].bend = int(lsb) + int(msb) * 128 - 8192; NoteUpdate_All(channel, Upd_Pitch); } @@ -1438,9 +1444,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, MIDIchannel::NoteInfo &info = *i; const int16_t tone = info.tone; const uint8_t vol = info.vol; - const int midiins = info.midiins; - const size_t insmeta = info.insmeta; - const adlinsdata &ains = opl.GetAdlMetaIns(insmeta); + const int midiins = static_cast<int>(info.midiins); + const adlinsdata2 &ains = *info.ains; AdlChannel::Location my_loc; my_loc.MidCh = MidCh; my_loc.note = info.note; @@ -1454,11 +1459,13 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, if(props_mask & Upd_Patch) { - opl.Patch(c, ins.insId); + opl.Patch(c, ins.ains); AdlChannel::LocationData *d = ch[c].users_find_or_create(my_loc); - if(d) { // inserts if necessary + if(d) // inserts if necessary + { d->sustained = false; d->vibdelay = 0; + d->fixed_sustain = (ains.ms_sound_kon == static_cast<uint16_t>(adlNoteOnMaxTime)); d->kon_time_until_neglible = ains.ms_sound_kon; d->ins = ins; } @@ -1492,7 +1499,9 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { opl.Touch_Real(c, 0); ch[c].koff_time_until_neglible = 0; - } else { + } + else + { ch[c].koff_time_until_neglible = ains.ms_sound_koff; } } @@ -1533,8 +1542,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, switch(opl.m_volumeScale) { + case OPL3::VOLUME_Generic: - case OPL3::VOLUME_CMF: { volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; @@ -1547,25 +1556,29 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, */ //volume = (int)(volume * std::sqrt( (double) ch[c].users.size() )); - if(opl.LogarithmicVolumes) - volume = volume * 127 / (127 * 127 * 127) / 2; - else - { - // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A) - volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0; - // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A) - //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0); - } + // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A) + volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0; + // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A) + //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0); + opl.Touch_Real(c, volume, brightness); //opl.Touch(c, volume); } break; + case OPL3::VOLUME_NATIVE: + { + volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; + volume = volume * 127 / (127 * 127 * 127) / 2; + opl.Touch_Real(c, volume, brightness); + } + break; + case OPL3::VOLUME_DMX: { volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1; //volume = 2 * (Ch[MidCh].volume) + 1; - volume = (DMX_volume_mapping_table[vol] * volume) >> 9; + volume = (DMX_volume_mapping_table[(vol < 128) ? vol : 127] * volume) >> 9; opl.Touch_Real(c, volume, brightness); } break; @@ -1610,26 +1623,29 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, // Don't bend a sustained note if(!d || !d->sustained) { - double bend = Ch[MidCh].bend + opl.GetAdlIns(ins.insId).finetune; + double midibend = Ch[MidCh].bend * Ch[MidCh].bendsense; + double bend = midibend + ins.ains.finetune; double phase = 0.0; + uint8_t vibrato = std::max(Ch[MidCh].vibrato, Ch[MidCh].aftertouch); + vibrato = std::max(vibrato, i->vibrato); if((ains.flags & adlinsdata::Flag_Pseudo4op) && ins.pseudo4op) { phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does) } - if(Ch[MidCh].vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay)) - bend += Ch[MidCh].vibrato * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos); + if(vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay)) + bend += static_cast<double>(vibrato) * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos); - #ifdef ADLMIDI_USE_DOSBOX_OPL -#define BEND_COEFFICIENT 172.00093 - #else -#define BEND_COEFFICIENT 172.4387 - #endif - opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (tone + bend + phase))); +#ifdef ADLMIDI_USE_DOSBOX_OPL +# define BEND_COEFFICIENT 172.00093 +#else +# define BEND_COEFFICIENT 172.4387 +#endif + opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (static_cast<double>(tone) + bend + phase))); #undef BEND_COEFFICIENT if(hooks.onNote) - hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, Ch[MidCh].bend); + hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, midibend); } } } @@ -1650,9 +1666,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) const size_t TrackCount = CurrentPositionNew.track.size(); const PositionNew RowBeginPosition(CurrentPositionNew); - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION double maxTime = 0.0; - #endif +#endif for(size_t tk = 0; tk < TrackCount; ++tk) { @@ -1670,10 +1686,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) for(size_t i = 0; i < track.pos->events.size(); i++) { const MidiEvent &evt = track.pos->events[i]; - #ifdef ENABLE_BEGIN_SILENCE_SKIPPING +#ifdef ENABLE_BEGIN_SILENCE_SKIPPING if(!CurrentPositionNew.began && (evt.type == MidiEvent::T_NOTEON)) CurrentPositionNew.began = true; - #endif +#endif if(isSeek && (evt.type == MidiEvent::T_NOTEON)) continue; HandleEvent(tk, evt, track.status); @@ -1681,10 +1697,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) break;//Stop event handling on catching loopEnd event! } - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION if(maxTime < track.pos->time) maxTime = track.pos->time; - #endif +#endif // Read next event time (unless the track just ended) if(track.status >= 0) { @@ -1694,11 +1710,11 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) } } - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, " \r"); std::fprintf(stdout, "Time: %10f; Audio: %10f\r", maxTime, CurrentPositionNew.absTimePosition); std::fflush(stdout); - #endif +#endif // Find shortest delay from all track uint64_t shortest = 0; @@ -1722,9 +1738,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) fraction<uint64_t> t = shortest * Tempo; - #ifdef ENABLE_BEGIN_SILENCE_SKIPPING +#ifdef ENABLE_BEGIN_SILENCE_SKIPPING if(CurrentPositionNew.began) - #endif +#endif CurrentPositionNew.wait += t.value(); //if(shortest > 0) UI.PrintLn("Delay %ld (%g)", shortest, (double)t.valuel()); @@ -1750,9 +1766,7 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) return true;//Has events in queue } -#endif -#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &status) { uint8_t *&ptr = *pptr; @@ -1800,6 +1814,14 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat evt.subtype = evtype; evt.data.insert(evt.data.begin(), data.begin(), data.end()); +#if 0 /* Print all tempo events */ + if(evt.subtype == MidiEvent::ST_TEMPOCHANGE) + { + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "Temp Change: %02X%02X%02X", evt.data[0], evt.data[1], evt.data[2]); + } +#endif + /* TODO: Store those meta-strings separately and give ability to read them * by external functions (to display song title and copyright in the player) */ if(evt.subtype == MidiEvent::ST_COPYRIGHT) @@ -1930,9 +1952,16 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat evt.data.push_back(*(ptr++)); evt.data.push_back(*(ptr++)); - if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0)) + /* TODO: Implement conversion of RSXX's note volumes out of synthesizer */ + /*if((opl.m_musicMode == OPL3::MODE_RSXX) && (evType == MidiEvent::T_NOTEON) && (evt.data[1] != 0)) + { + //NOT WORKING YET + evt.type = MidiEvent::T_NOTETOUCH; + } + else */if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0)) + { evt.type = MidiEvent::T_NOTEOFF; // Note ON with zero velocity is Note OFF! - //111'th loopStart controller (RPG Maker and others) + } //111'th loopStart controller (RPG Maker and others) else if((evType == MidiEvent::T_CTRLCHANGE) && (evt.data[0] == 111)) { //Change event type to custom Loop Start event and clear data @@ -1956,7 +1985,7 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat return evt; } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ const std::string &MIDIplay::getErrorString() { @@ -2045,7 +2074,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu v |= 0x30; //std::printf("OPL poke %02X, %02X\n", i, v); //std::fflush(stdout); - opl.PokeN(0, i, v); + opl.Poke(0, i, v); return; } @@ -2125,15 +2154,15 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu } } } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ -int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const +int64_t MIDIplay::CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const { int64_t s = -ch[c].koff_time_until_neglible; // Same midi-instrument = some stability //if(c == MidCh) s += 4; - for (AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next) + for(AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next) { s -= 4000; @@ -2174,7 +2203,7 @@ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::Not // increase the score slightly. unsigned n_evacuation_stations = 0; - for(unsigned c2 = 0; c2 < opl.NumChannels; ++c2) + for(size_t c2 = 0; c2 < static_cast<size_t>(opl.NumChannels); ++c2) { if(c2 == c) continue; @@ -2275,11 +2304,11 @@ void MIDIplay::KillOrEvacuate(size_t from_channel, hooks.onNote(hooks.onNote_userData, (int)from_channel, i->tone, - i->midiins, 0, 0.0); + static_cast<int>(i->midiins), 0, 0.0); hooks.onNote(hooks.onNote_userData, (int)c, i->tone, - i->midiins, + static_cast<int>(i->midiins), i->vol, 0.0); } @@ -2358,7 +2387,12 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB) switch(addr + nrpn * 0x10000 + MSB * 0x20000) { case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity - Ch[MidCh].bendsense = value / 8192.0; + Ch[MidCh].bendsense_msb = value; + Ch[MidCh].updateBendSensitivity(); + break; + case 0x0000 + 0*0x10000 + 0*0x20000: // Pitch-bender sensitivity LSB + Ch[MidCh].bendsense_lsb = value; + Ch[MidCh].updateBendSensitivity(); break; case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed if(value == 64) Ch[MidCh].vibspeed = 1.0; @@ -2412,7 +2446,7 @@ void MIDIplay::UpdateVibrato(double amount) { for(size_t a = 0, b = Ch.size(); a < b; ++a) { - if(Ch[a].vibrato && !Ch[a].activenotes_empty()) + if(Ch[a].hasVibrato() && !Ch[a].activenotes_empty()) { NoteUpdate_All(static_cast<uint16_t>(a), Upd_Pitch); Ch[a].vibpos += amount * Ch[a].vibspeed; @@ -2442,9 +2476,9 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed { // If there is an adlib channel that has multiple notes // simulated on the same channel, arpeggio them. - #if 0 +#if 0 const unsigned desired_arpeggio_rate = 40; // Hz (upper limit) - #if 1 +# if 1 static unsigned cache = 0; amount = amount; // Ignore amount. Assume we get a constant rate. cache += MaxSamplesAtTime * desired_arpeggio_rate; @@ -2452,17 +2486,17 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed if(cache < PCM_RATE) return; cache %= PCM_RATE; - #else +# else static double arpeggio_cache = 0; arpeggio_cache += amount * desired_arpeggio_rate; if(arpeggio_cache < 1.0) return; arpeggio_cache = 0.0; - #endif - #endif - static unsigned arpeggio_counter = 0; - ++arpeggio_counter; +# endif +#endif + + ++m_arpeggioCounter; for(uint32_t c = 0; c < opl.NumChannels; ++c) { @@ -2483,8 +2517,8 @@ retry_arpeggio: if(n_users >= 4) rate_reduction = 1; - for(unsigned count = (arpeggio_counter / rate_reduction) % n_users, - n = 0; n < count; ++n) + for(size_t count = (m_arpeggioCounter / rate_reduction) % n_users, + n = 0; n < count; ++n) i = i->next; if(i->sustained == false) @@ -2512,36 +2546,48 @@ retry_arpeggio: #ifndef ADLMIDI_DISABLE_CPP_EXTRAS +struct AdlInstrumentTester::Impl +{ + uint32_t cur_gm; + uint32_t ins_idx; + std::vector<uint32_t> adl_ins_list; + OPL3 *opl; + MIDIplay *play; +}; + ADLMIDI_EXPORT AdlInstrumentTester::AdlInstrumentTester(ADL_MIDIPlayer *device) + : P(new Impl) { - cur_gm = 0; - ins_idx = 0; - play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); - if(!play) - return; - opl = &play->opl; + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + P->cur_gm = 0; + P->ins_idx = 0; + P->play = play; + P->opl = play ? &play->opl : NULL; } ADLMIDI_EXPORT AdlInstrumentTester::~AdlInstrumentTester() -{} +{ + delete P; +} ADLMIDI_EXPORT void AdlInstrumentTester::FindAdlList() { const unsigned NumBanks = (unsigned)adl_getBanksCount(); std::set<unsigned> adl_ins_set; for(unsigned bankno = 0; bankno < NumBanks; ++bankno) - adl_ins_set.insert(banks[bankno][cur_gm]); - adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end()); - ins_idx = 0; + adl_ins_set.insert(banks[bankno][P->cur_gm]); + P->adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end()); + P->ins_idx = 0; NextAdl(0); - opl->Silence(); + P->opl->Silence(); } ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127 { - if(opl->LogarithmicVolumes) + OPL3 *opl = P->opl; + if(opl->m_volumeScale == OPL3::VOLUME_NATIVE) opl->Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2); else { @@ -2554,11 +2600,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // V ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) { - if(adl_ins_list.empty()) FindAdlList(); - const unsigned meta = adl_ins_list[ins_idx]; - const adlinsdata &ains = opl->GetAdlMetaIns(meta); + MIDIplay *play = P->play; + OPL3 *opl = P->opl; + if(P->adl_ins_list.empty()) FindAdlList(); + const unsigned meta = P->adl_ins_list[P->ins_idx]; + const adlinsdata2 ains(adlins[meta]); - int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50); + int tone = (P->cur_gm & 128) ? (P->cur_gm & 127) : (note + 50); if(ains.tone) { /*if(ains.tone < 20) @@ -2570,16 +2618,15 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) tone -= ains.tone - 128; } double hertz = 172.00093 * std::exp(0.057762265 * (tone + 0.0)); - int i[2] = { ains.adlno1, ains.adlno2 }; int32_t adlchannel[2] = { 0, 3 }; - if(i[0] == i[1]) + if(ains.adl[0] == ains.adl[1]) { adlchannel[1] = -1; adlchannel[0] = 6; // single-op if(play->hooks.onDebugMessage) { play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData, - "noteon at %d(%d) for %g Hz\n", adlchannel[0], i[0], hertz); + "noteon at %d for %g Hz\n", adlchannel[0], hertz); } } else @@ -2587,7 +2634,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) if(play->hooks.onDebugMessage) { play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData, - "noteon at %d(%d) and %d(%d) for %g Hz\n", adlchannel[0], i[0], adlchannel[1], i[1], hertz); + "noteon at %d and %d for %g Hz\n", adlchannel[0], adlchannel[1], hertz); } } @@ -2597,7 +2644,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) for(unsigned c = 0; c < 2; ++c) { if(adlchannel[c] < 0) continue; - opl->Patch((uint16_t)adlchannel[c], (uint16_t)i[c]); + opl->Patch((uint16_t)adlchannel[c], ains.adl[c]); opl->Touch_Real((uint16_t)adlchannel[c], 127 * 127 * 100); opl->Pan((uint16_t)adlchannel[c], 0x30); opl->NoteOn((uint16_t)adlchannel[c], hertz); @@ -2606,17 +2653,18 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) ADLMIDI_EXPORT void AdlInstrumentTester::NextGM(int offset) { - cur_gm = (cur_gm + 256 + (uint32_t)offset) & 0xFF; + P->cur_gm = (P->cur_gm + 256 + (uint32_t)offset) & 0xFF; FindAdlList(); } ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) { - if(adl_ins_list.empty()) FindAdlList(); + //OPL3 *opl = P->opl; + if(P->adl_ins_list.empty()) FindAdlList(); const unsigned NumBanks = (unsigned)adl_getBanksCount(); - ins_idx = (uint32_t)((int32_t)ins_idx + (int32_t)adl_ins_list.size() + offset) % adl_ins_list.size(); + P->ins_idx = (uint32_t)((int32_t)P->ins_idx + (int32_t)P->adl_ins_list.size() + offset) % P->adl_ins_list.size(); - #if 0 +#if 0 UI.Color(15); std::fflush(stderr); std::printf("SELECTED G%c%d\t%s\n", @@ -2625,12 +2673,12 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) std::fflush(stdout); UI.Color(7); std::fflush(stderr); - #endif +#endif - for(unsigned a = 0; a < adl_ins_list.size(); ++a) + for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a) { - const unsigned i = adl_ins_list[a]; - const adlinsdata &ains = opl->GetAdlMetaIns(i); + const unsigned i = P->adl_ins_list[a]; + const adlinsdata2 ains(adlins[i]); char ToneIndication[8] = " "; if(ains.tone) @@ -2645,13 +2693,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) } std::printf("%s%s%s%u\t", ToneIndication, - ains.adlno1 != ains.adlno2 ? "[2]" : " ", - (ins_idx == a) ? "->" : "\t", + ains.adl[0] != ains.adl[1] ? "[2]" : " ", + (P->ins_idx == a) ? "->" : "\t", i ); for(unsigned bankno = 0; bankno < NumBanks; ++bankno) - if(banks[bankno][cur_gm] == i) + if(banks[bankno][P->cur_gm] == i) std::printf(" %u", bankno); std::printf("\n"); @@ -2685,9 +2733,9 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch) NextGM(+1); break; case 3: - #if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)) +#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)) case 27: - #endif +#endif return false; default: const char *p = std::strchr(notes, ch); @@ -2697,7 +2745,7 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch) return true; } -#endif//ADLMIDI_DISABLE_CPP_EXTRAS +#endif /* ADLMIDI_DISABLE_CPP_EXTRAS */ // Implement the user map data structure. @@ -2737,13 +2785,15 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_allocate() MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_find_or_create(Location loc) { LocationData *user = users_find(loc); - if(!user) { + if(!user) + { user = users_allocate(); if(!user) return NULL; LocationData *prev = user->prev, *next = user->next; *user = LocationData(); - user->prev = prev; user->next = next; + user->prev = prev; + user->next = next; user->loc = loc; } return user; @@ -2759,7 +2809,8 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_insert(const Loc return NULL; LocationData *prev = user->prev, *next = user->next; *user = x; - user->prev = prev; user->next = next; + user->prev = prev; + user->next = next; } return user; } @@ -2792,8 +2843,10 @@ void MIDIplay::AdlChannel::users_clear() void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count) { + ADL_UNUSED(count);//Avoid warning for release builds assert(count <= users_max); - if(users == users_first && users) { + if(users == users_first && users) + { // self assignment assert(users_size == count); return; @@ -2801,17 +2854,20 @@ void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count) users_clear(); const LocationData *src_cell = users; // move to the last - if(src_cell) { + if(src_cell) + { while(src_cell->next) src_cell = src_cell->next; } // push cell copies in reverse order - while(src_cell) { + while(src_cell) + { LocationData *dst_cell = users_allocate(); assert(dst_cell); LocationData *prev = dst_cell->prev, *next = dst_cell->next; *dst_cell = *src_cell; - dst_cell->prev = prev; dst_cell->next = next; + dst_cell->prev = prev; + dst_cell->next = next; src_cell = src_cell->prev; } assert(users_size == count); diff --git a/src/adlmidi_mus2mid.c b/src/adlmidi_mus2mid.c index 8268198..3f3e1b8 100644 --- a/src/adlmidi_mus2mid.c +++ b/src/adlmidi_mus2mid.c @@ -416,7 +416,7 @@ int AdlMidi_mus2midi(uint8_t *in, uint32_t insize, memcpy(ctx.dst_ptr, temp_buffer, out_local - temp_buffer); ctx.dst_ptr += out_local - temp_buffer; - ctx.dstrem -= out_local - temp_buffer; + ctx.dstrem -= (uint32_t)(out_local - temp_buffer); } if (event & 128) { diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 66254b6..16a481d 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -129,81 +129,56 @@ static const unsigned short Channels[23] = Ports: ??? */ - -const adlinsdata &OPL3::GetAdlMetaIns(size_t n) +void OPL3::setEmbeddedBank(unsigned int bank) { - return (n & DynamicMetaInstrumentTag) ? - dynamic_metainstruments[n & ~DynamicMetaInstrumentTag] - : adlins[n]; -} + AdlBank = bank; + //Embedded banks are supports 128:128 GM set only + dynamic_banks.clear(); -size_t OPL3::GetAdlMetaNumber(size_t midiins) -{ - return (AdlBank == ~0u) ? - (midiins | DynamicMetaInstrumentTag) - : banks[AdlBank][midiins]; -} + if(bank >= static_cast<unsigned int>(maxAdlBanks())) + return; -const adldata &OPL3::GetAdlIns(size_t insno) -{ - return (insno & DynamicInstrumentTag) - ? dynamic_instruments[insno & ~DynamicInstrumentTag] - : adl[insno]; + Bank *bank_pair[2] = + { + &dynamic_banks[0], + &dynamic_banks[PercussionTag] + }; + + for(unsigned i = 0; i < 256; ++i) + { + size_t meta = banks[bank][i]; + adlinsdata2 &ins = bank_pair[i / 128]->ins[i % 128]; + ins = adlinsdata2(adlins[meta]); + } } -void OPL3::setEmbeddedBank(unsigned int bank) +static adlinsdata2 makeEmptyInstrument() { - AdlBank = bank; - //Embedded banks are supports 128:128 GM set only - dynamic_percussion_offset = 128; - dynamic_melodic_banks.clear(); - dynamic_percussion_banks.clear(); + adlinsdata2 ins; + memset(&ins, 0, sizeof(adlinsdata2)); + ins.flags = adlinsdata::Flag_NoSound; + return ins; } +const adlinsdata2 OPL3::emptyInstrument = makeEmptyInstrument(); OPL3::OPL3() : - dynamic_percussion_offset(128), - DynamicInstrumentTag(0x8000u), - DynamicMetaInstrumentTag(0x4000000u), NumCards(1), - AdlBank(0), NumFourOps(0), HighTremoloMode(false), HighVibratoMode(false), AdlPercussionMode(false), - LogarithmicVolumes(false), - //CartoonersVolumes(false), m_musicMode(MODE_MIDI), m_volumeScale(VOLUME_Generic) -{} - -void OPL3::Poke(size_t card, uint32_t index, uint32_t value) { - #ifdef ADLMIDI_HW_OPL - (void)card; - unsigned o = index >> 8; - unsigned port = OPLBase + o * 2; - - #ifdef __DJGPP__ - outportb(port, index); - for(unsigned c = 0; c < 6; ++c) inportb(port); - outportb(port + 1, value); - for(unsigned c = 0; c < 35; ++c) inportb(port); - #endif//__DJGPP__ - - #ifdef __WATCOMC__ - outp(port, index); - for(uint16_t c = 0; c < 6; ++c) inp(port); - outp(port + 1, value); - for(uint16_t c = 0; c < 35; ++c) inp(port); - #endif//__WATCOMC__ - - #else//ADLMIDI_HW_OPL - cardsOP2[card]->writeReg(static_cast<uint16_t>(index), static_cast<uint8_t>(value)); - #endif//ADLMIDI_HW_OPL +#ifdef DISABLE_EMBEDDED_BANKS + AdlBank = ~0u; +#else + setEmbeddedBank(0); +#endif } -void OPL3::PokeN(size_t card, uint16_t index, uint8_t value) +void OPL3::Poke(size_t card, uint16_t index, uint8_t value) { #ifdef ADLMIDI_HW_OPL (void)card; @@ -282,10 +257,9 @@ void OPL3::Touch_Real(unsigned c, unsigned volume, uint8_t brightness) volume = 63; size_t card = c / 23, cc = c % 23; - size_t i = ins[c]; + const adldata &adli = ins[c]; uint16_t o1 = Operators[cc * 2 + 0]; uint16_t o2 = Operators[cc * 2 + 1]; - const adldata &adli = GetAdlIns(i); uint8_t x = adli.modulator_40, y = adli.carrier_40; uint16_t mode = 1; // 2-op AM @@ -295,22 +269,22 @@ void OPL3::Touch_Real(unsigned c, unsigned volume, uint8_t brightness) } else if(four_op_category[c] == 1 || four_op_category[c] == 2) { - size_t i0, i1; + const adldata *i0, *i1; if(four_op_category[c] == 1) { - i0 = i; - i1 = ins[c + 3]; + i0 = &adli; + i1 = &ins[c + 3]; mode = 2; // 4-op xx-xx ops 1&2 } else { - i0 = ins[c - 3]; - i1 = i; + i0 = &ins[c - 3]; + i1 = &adli; mode = 6; // 4-op xx-xx ops 3&4 } - mode += (GetAdlIns(i0).feedconn & 1) + (GetAdlIns(i1).feedconn & 1) * 2; + mode += (i0->feedconn & 1) + (i1->feedconn & 1) * 2; } static const bool do_ops[10][2] = @@ -377,14 +351,13 @@ void OPL3::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127 } }*/ -void OPL3::Patch(uint16_t c, size_t i) +void OPL3::Patch(uint16_t c, const adldata &adli) { uint16_t card = c / 23, cc = c % 23; static const uint8_t data[4] = {0x20, 0x60, 0x80, 0xE0}; - ins[c] = i; + ins[c] = adli; uint16_t o1 = Operators[cc * 2 + 0]; uint16_t o2 = Operators[cc * 2 + 1]; - const adldata &adli = GetAdlIns(i); unsigned x = adli.modulator_E862, y = adli.carrier_E862; for(unsigned a = 0; a < 4; ++a, x >>= 8, y >>= 8) @@ -400,7 +373,7 @@ void OPL3::Pan(unsigned c, unsigned value) unsigned card = c / 23, cc = c % 23; if(Channels[cc] != 0xFFF) - Poke(card, 0xC0 + Channels[cc], GetAdlIns(ins[c]).feedconn | value); + Poke(card, 0xC0 + Channels[cc], ins[c].feedconn | value); } void OPL3::Silence() // Silence all OPL channels. @@ -484,9 +457,8 @@ void OPL3::ChangeVolumeRangesModel(ADLMIDI_VolumeModels volumeModel) m_volumeScale = OPL3::VOLUME_Generic; break; - case ADLMIDI_VolumeModel_CMF: - LogarithmicVolumes = true; - m_volumeScale = OPL3::VOLUME_CMF; + case ADLMIDI_VolumeModel_NativeOPL3: + m_volumeScale = OPL3::VOLUME_NATIVE; break; case ADLMIDI_VolumeModel_DMX: @@ -517,6 +489,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE) #ifndef ADLMIDI_HW_OPL ClearChips(); #endif + (void)emulator; (void)PCM_RATE; ins.clear(); pit.clear(); @@ -527,7 +500,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE) #endif NumChannels = NumCards * 23; - ins.resize(NumChannels, 189); + ins.resize(NumChannels, adl[adlDefaultNumber]); pit.resize(NumChannels, 0); regBD.resize(NumCards, 0); four_op_category.resize(NumChannels, 0); @@ -571,7 +544,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE) for(unsigned a = 0; a < 18; ++a) Poke(i, 0xB0 + Channels[a], 0x00); for(unsigned a = 0; a < sizeof(data) / sizeof(*data); a += 2) - PokeN(i, data[a], static_cast<uint8_t>(data[a + 1])); + Poke(i, data[a], static_cast<uint8_t>(data[a + 1])); Poke(i, 0x0BD, regBD[i] = (HighTremoloMode * 0x80 + HighVibratoMode * 0x40 + AdlPercussionMode * 0x20)); diff --git a/src/adlmidi_private.cpp b/src/adlmidi_private.cpp index 1f3cb7d..77319d7 100644 --- a/src/adlmidi_private.cpp +++ b/src/adlmidi_private.cpp @@ -34,19 +34,22 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device) if(play->opl.AdlBank == ~0u) { //For custom bank - for(size_t a = 0; a < play->opl.dynamic_metainstruments.size(); ++a) + OPL3::BankMap::iterator it = play->opl.dynamic_banks.begin(); + OPL3::BankMap::iterator end = play->opl.dynamic_banks.end(); + for(; it != end; ++it) { - size_t div = (a >= play->opl.dynamic_percussion_offset) ? 1 : 0; - ++n_total[div]; - adlinsdata &ins = play->opl.dynamic_metainstruments[a]; - if((ins.adlno1 != ins.adlno2) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0)) - ++n_fourop[div]; + uint16_t bank = it->first; + unsigned div = (bank & OPL3::PercussionTag) ? 1 : 0; + for(unsigned i = 0; i < 128; ++i) + { + adlinsdata2 &ins = it->second.ins[i]; + if(ins.flags & adlinsdata::Flag_NoSound) + continue; + if((ins.adl[0] != ins.adl[1]) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0)) + ++n_fourop[div]; + ++n_total[div]; + } } - - play->m_setup.NumFourOps = - (n_fourop[0] >= 128 * 7 / 8) ? play->m_setup.NumCards * 6 - : (n_fourop[0] < 128 * 1 / 8) ? (n_fourop[1] > 0 ? 4 : 0) - : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); } else { @@ -57,27 +60,34 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device) if(insno == 198) continue; ++n_total[a / 128]; - const adlinsdata &ins = adlins[insno]; - if((ins.adlno1 != ins.adlno2) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0)) + adlinsdata2 ins(adlins[insno]); + if(ins.flags & adlinsdata::Flag_Real4op) ++n_fourop[a / 128]; } - - play->m_setup.NumFourOps = - (n_fourop[0] >= (n_total[0] % 128) * 7 / 8) ? play->m_setup.NumCards * 6 - : (n_fourop[0] < (n_total[0] % 128) * 1 / 8) ? 0 - : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); } - play->opl.NumFourOps = play->m_setup.NumFourOps; + unsigned numFourOps = 0; - if(n_fourop[0] >= n_total[0] * 15 / 16 && play->m_setup.NumFourOps == 0) - { - play->setErrorString("ERROR: You have selected a bank that consists almost exclusively of four-op patches.\n" - " The results (silence + much cpu load) would be probably\n" - " not what you want, therefore ignoring the request.\n"); - return -1; - } + // All 2ops (no 4ops) + if((n_fourop[0] == 0) && (n_fourop[1] == 0)) + numFourOps = 0; + // All 2op melodics and Some (or All) 4op drums + else if((n_fourop[0] == 0) && (n_fourop[1] > 0)) + numFourOps = 2; + // Many 4op melodics + else if((n_fourop[0] >= (n_total[0] * 7) / 8)) + numFourOps = 6; + // Few 4op melodics + else if(n_fourop[0] > 0) + numFourOps = 4; + +/* //Old formula + unsigned NumFourOps = ((n_fourop[0] == 0) && (n_fourop[1] == 0)) ? 0 + : (n_fourop[0] >= (n_total[0] * 7) / 8) ? play->m_setup.NumCards * 6 + : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); +*/ + + play->opl.NumFourOps = play->m_setup.NumFourOps = (numFourOps * play->m_setup.NumCards); return 0; } - diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 9fd6f97..2499bad 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -35,6 +35,9 @@ # endif #endif +// Require declarations of unstable API for extern "C" +#define ADLMIDI_UNSTABLE_API + #ifdef _WIN32 #define NOMINMAX #endif @@ -88,17 +91,13 @@ typedef int32_t ssize_t; #include <cstdarg> #include <cstdio> #include <cassert> -#if !(defined(__APPLE__) && defined(__GLIBCXX__)) && !defined(__ANDROID__) -#include <cinttypes> //PRId32, PRIu32, etc. -#else -#include <inttypes.h> -#endif #include <vector> // vector #include <deque> // deque #include <cmath> // exp, log, ceil #if defined(__WATCOMC__) #include <math.h> // round, sqrt #endif +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <limits> // numeric_limit @@ -110,11 +109,26 @@ typedef int32_t ssize_t; #include <deque> #include <algorithm> -#ifdef _MSC_VER -#pragma warning(disable:4319) -#pragma warning(disable:4267) -#pragma warning(disable:4244) -#pragma warning(disable:4146) +/* + * Workaround for some compilers are has no those macros in their headers! + */ +#ifndef INT8_MIN +#define INT8_MIN (-0x7f - 1) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-0x7fff - 1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-0x7fffffff - 1) +#endif +#ifndef INT8_MAX +#define INT8_MAX 0x7f +#endif +#ifndef INT16_MAX +#define INT16_MAX 0x7fff +#endif +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff #endif #include "fraction.hpp" @@ -127,6 +141,8 @@ typedef int32_t ssize_t; #ifndef ADLMIDI_DISABLE_CPP_EXTRAS #include "adlmidi.hpp" //Extra C++ API #endif +#include "adlmidi_ptr.hpp" +#include "adlmidi_bankmap.h" #define ADL_UNUSED(x) (void)x @@ -144,12 +160,14 @@ inline Real adl_cvtReal(int32_t x) { return x * ((Real)1 / INT16_MAX); } + inline int32_t adl_cvtS16(int32_t x) { - x = (x < INT16_MIN) ? INT16_MIN : x; - x = (x > INT16_MAX) ? INT16_MAX : x; + x = (x < INT16_MIN) ? (INT16_MIN) : x; + x = (x > INT16_MAX) ? (INT16_MAX) : x; return x; } + inline int32_t adl_cvtS8(int32_t x) { return adl_cvtS16(x) / 256; @@ -181,117 +199,6 @@ inline int32_t adl_cvtU32(int32_t x) return (uint32_t)adl_cvtS32(x) - (uint32_t)INT32_MIN; } -/* - Smart pointer for C heaps, created with malloc() call. - FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it -*/ -template<class PTR> -class AdlMIDI_CPtr -{ - PTR *m_p; -public: - AdlMIDI_CPtr() : m_p(NULL) {} - ~AdlMIDI_CPtr() - { - reset(NULL); - } - - void reset(PTR *p = NULL) - { - if(p != m_p) { - if(m_p) - free(m_p); - m_p = p; - } - } - - PTR *get() - { - return m_p; - } - PTR &operator*() - { - return *m_p; - } - PTR *operator->() - { - return m_p; - } -private: - AdlMIDI_CPtr(const AdlMIDI_CPtr &); - AdlMIDI_CPtr &operator=(const AdlMIDI_CPtr &); -}; - -/* - Shared pointer with non-atomic counter - FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it -*/ -template<class VALUE> -class AdlMIDI_SPtr -{ - VALUE *m_p; - size_t *m_counter; -public: - AdlMIDI_SPtr() : m_p(NULL), m_counter(NULL) {} - ~AdlMIDI_SPtr() - { - reset(NULL); - } - - AdlMIDI_SPtr(const AdlMIDI_SPtr &other) - : m_p(other.m_p), m_counter(other.m_counter) - { - if(m_counter) - ++*m_counter; - } - - AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other) - { - if(this == &other) - return *this; - reset(); - m_p = other.m_p; - m_counter = other.m_counter; - if(m_counter) - ++*m_counter; - return *this; - } - - void reset(VALUE *p = NULL) - { - if(p != m_p) { - if(m_p && --*m_counter == 0) - delete m_p; - m_p = p; - if(!p) { - if(m_counter) { - delete m_counter; - m_counter = NULL; - } - } - else - { - if(!m_counter) - m_counter = new size_t; - *m_counter = 1; - } - } - } - - VALUE *get() - { - return m_p; - } - VALUE &operator*() - { - return *m_p; - } - VALUE *operator->() - { - return m_p; - } -}; - class MIDIplay; struct ADL_MIDIPlayer; class OPL3 @@ -306,27 +213,23 @@ public: std::vector<AdlMIDI_SPtr<OPLChipBase > > cardsOP2; #endif private: - std::vector<size_t> ins; // index to adl[], cached, needed by Touch() + std::vector<adldata> ins; // patch data, cached, needed by Touch() std::vector<uint8_t> pit; // value poked to B0, cached, needed by NoteOff)( std::vector<uint8_t> regBD; friend int adlRefreshNumCards(ADL_MIDIPlayer *device); - //! Meta information about every instrument - std::vector<adlinsdata> dynamic_metainstruments; // Replaces adlins[] when CMF file - //! Raw instrument data ready to be sent to the chip - std::vector<adldata> dynamic_instruments; // Replaces adl[] when CMF file - size_t dynamic_percussion_offset; - - typedef std::map<uint16_t, size_t> BankMap; - BankMap dynamic_melodic_banks; - BankMap dynamic_percussion_banks; - const unsigned DynamicInstrumentTag /* = 0x8000u*/, - DynamicMetaInstrumentTag /* = 0x4000000u*/; - const adlinsdata &GetAdlMetaIns(size_t n); - size_t GetAdlMetaNumber(size_t midiins); - const adldata &GetAdlIns(size_t insno); +public: + struct Bank + { + adlinsdata2 ins[128]; + }; + typedef BasicBankMap<Bank> BankMap; + BankMap dynamic_banks; + AdlBankSetup dynamic_bank_setup; public: void setEmbeddedBank(unsigned int bank); + static const adlinsdata2 emptyInstrument; + enum { PercussionTag = 1 << 15 }; //! Total number of running concurrent emulated chips unsigned int NumCards; @@ -342,8 +245,8 @@ public: bool AdlPercussionMode; //! Carriers-only are scaled by default by volume level. This flag will tell to scale modulators too. bool ScaleModulators; - //! Required to play CMF files. Can be turned on by using of "CMF" volume model - bool LogarithmicVolumes; + // ! Required to play CMF files. Can be turned on by using of "CMF" volume model + //bool LogarithmicVolumes; //[REPLACED WITH "m_volumeScale == VOLUME_NATIVE", DEPRECATED!!!] // ! Required to play EA-MUS files [REPLACED WITH "m_musicMode", DEPRECATED!!!] //bool CartoonersVolumes; enum MusicMode @@ -359,7 +262,7 @@ public: enum VolumesScale { VOLUME_Generic, - VOLUME_CMF, + VOLUME_NATIVE, VOLUME_DMX, VOLUME_APOGEE, VOLUME_9X @@ -375,15 +278,14 @@ public: // 7 = percussion Hihat // 8 = percussion slave - void Poke(size_t card, uint32_t index, uint32_t value); - void PokeN(size_t card, uint16_t index, uint8_t value); + void Poke(size_t card, uint16_t index, uint8_t value); void NoteOff(size_t c); void NoteOn(unsigned c, double hertz); void Touch_Real(unsigned c, unsigned volume, uint8_t brightness = 127); //void Touch(unsigned c, unsigned volume) - void Patch(uint16_t c, size_t i); + void Patch(uint16_t c, const adldata &adli); void Pan(unsigned c, unsigned value); void Silence(); void updateFlags(); @@ -578,7 +480,7 @@ public: bool eof() { if(fp) - return std::feof(fp); + return (std::feof(fp) != 0); else return mp_tell >= mp_size; } @@ -596,9 +498,15 @@ public: uint8_t bank_lsb, bank_msb; uint8_t patch; uint8_t volume, expression; - uint8_t panning, vibrato, sustain; + uint8_t panning, vibrato, aftertouch, sustain; + //! Per note Aftertouch values + uint8_t noteAftertouch[128]; + //! Is note aftertouch has any non-zero value + bool noteAfterTouchInUse; char ____padding[6]; - double bend, bendsense; + int bend; + double bendsense; + int bendsense_lsb, bendsense_msb; double vibpos, vibspeed, vibdepth; int64_t vibdelay; uint8_t lastlrpn, lastmrpn; @@ -611,14 +519,15 @@ public: bool active; // Current pressure uint8_t vol; - char ____padding[1]; + // Note vibrato (a part of Note Aftertouch feature) + uint8_t vibrato; // Tone selected on noteon: int16_t tone; char ____padding2[4]; - // Patch selected on noteon; index to banks[AdlBank][] + // Patch selected on noteon; index to bank.ins[] size_t midiins; - // Index to physical adlib data structure, adlins[] - size_t insmeta; + // Patch selected + const adlinsdata2 *ains; enum { MaxNumPhysChans = 2, @@ -629,18 +538,18 @@ public: //! Destination chip channel uint16_t chip_chan; //! ins, inde to adl[] - size_t insId; + adldata ains; //! Is this voice must be detunable? bool pseudo4op; void assign(const Phys &oth) { - insId = oth.insId; + ains = oth.ains; pseudo4op = oth.pseudo4op; } bool operator==(const Phys &oth) const { - return (insId == oth.insId) && (pseudo4op == oth.pseudo4op); + return (ains == oth.ains) && (pseudo4op == oth.pseudo4op); } bool operator!=(const Phys &oth) const { @@ -660,7 +569,7 @@ public: ph = &chip_channels[i]; return ph; } - Phys *phys_find_or_create(unsigned chip_chan) + Phys *phys_find_or_create(uint16_t chip_chan) { Phys *ph = phys_find(chip_chan); if(!ph) { @@ -671,7 +580,7 @@ public: } return ph; } - Phys *phys_ensure_find_or_create(unsigned chip_chan) + Phys *phys_ensure_find_or_create(uint16_t chip_chan) { Phys *ph = phys_find_or_create(chip_chan); assert(ph); @@ -679,9 +588,9 @@ public: } void phys_erase_at(const Phys *ph) { - unsigned pos = ph - chip_channels; - assert(pos < chip_channels_count); - for(unsigned i = pos + 1; i < chip_channels_count; ++i) + intptr_t pos = ph - chip_channels; + assert(pos < static_cast<intptr_t>(chip_channels_count)); + for(intptr_t i = pos + 1; i < static_cast<intptr_t>(chip_channels_count); ++i) chip_channels[i - 1] = chip_channels[i]; --chip_channels_count; } @@ -707,7 +616,7 @@ public: for(++ptr; ptr && !ptr->active;) ptr = (ptr->note == 127) ? 0 : (ptr + 1); return *this; - }; + } activenoteiterator operator++(int) { activenoteiterator pos = *this; @@ -770,7 +679,7 @@ public: void activenotes_clear() { - for(unsigned i = 0; i < 128; ++i) { + for(uint8_t i = 0; i < 128; ++i) { activenotes[i].note = i; activenotes[i].active = false; } @@ -790,12 +699,17 @@ public: } void resetAllControllers() { - bend = 0.0; - bendsense = 2 / 8192.0; + bend = 0; + bendsense_msb = 2; + bendsense_lsb = 0; + updateBendSensitivity(); volume = 100; expression = 127; sustain = 0; vibrato = 0; + aftertouch = 0; + std::memset(noteAftertouch, 0, 128); + noteAfterTouchInUse = false; vibspeed = 2 * 3.141592653 * 5.0; vibdepth = 0.5 / 127; vibdelay = 0; @@ -803,6 +717,15 @@ public: portamento = 0; brightness = 127; } + bool hasVibrato() + { + return (vibrato > 0) || (aftertouch > 0) || noteAfterTouchInUse; + } + void updateBendSensitivity() + { + int cent = bendsense_msb * 128 + bendsense_lsb; + bendsense = cent * (1.0 / (128 * 8192)); + } MIDIchannel() { activenotes_clear(); @@ -829,6 +752,9 @@ public: bool sustained; char ____padding[7]; MIDIchannel::NoteInfo::Phys ins; // a copy of that in phys[] + //! Has fixed sustain, don't iterate "on" timeout + bool fixed_sustain; + //! Timeout until note will be allowed to be killed by channel manager while it is on int64_t kon_time_until_neglible; int64_t vibdelay; }; @@ -858,15 +784,21 @@ public: AdlChannel(const AdlChannel &oth): koff_time_until_neglible(oth.koff_time_until_neglible) { - users_assign(oth.users_first, oth.users_size); + if(oth.users_first) + { + users_first = NULL; + users_assign(oth.users_first, oth.users_size); + } + else + users_clear(); } AdlChannel &operator=(const AdlChannel &oth) - { - koff_time_until_neglible = oth.koff_time_until_neglible; - users_assign(oth.users_first, oth.users_size); - return *this; - } + { + koff_time_until_neglible = oth.koff_time_until_neglible; + users_assign(oth.users_first, oth.users_size); + return *this; + } void AddAge(int64_t ms); }; @@ -1049,6 +981,8 @@ private: char ____padding[7]; std::vector<AdlChannel> ch; + //! Counter of arpeggio processing + size_t m_arpeggioCounter; #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER std::vector<std::vector<uint8_t> > TrackData; @@ -1272,7 +1206,7 @@ private: // Determine how good a candidate this adlchannel // would be for playing a note from this instrument. - int64_t CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t /*MidCh*/) const; + int64_t CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t /*MidCh*/) const; // A new note will be played on this channel using this instrument. // Kill existing notes on this channel (or don't, if we do arpeggio) diff --git a/src/adlmidi_ptr.hpp b/src/adlmidi_ptr.hpp new file mode 100644 index 0000000..7d1086b --- /dev/null +++ b/src/adlmidi_ptr.hpp @@ -0,0 +1,217 @@ +/* + * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation + * + * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> + * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> + * + * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: + * http://iki.fi/bisqwit/source/adlmidi.html + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ADLMIDI_PTR_HPP_THING +#define ADLMIDI_PTR_HPP_THING + +#include <algorithm> // swap +#include <stddef.h> +#include <stdlib.h> + +/* + Generic deleters for smart pointers + */ +template <class T> +struct ADLMIDI_DefaultDelete +{ + void operator()(T *x) { delete x; } +}; +template <class T> +struct ADLMIDI_DefaultArrayDelete +{ + void operator()(T *x) { delete[] x; } +}; +struct ADLMIDI_CDelete +{ + void operator()(void *x) { free(x); } +}; + +/* + Safe unique pointer for C++98, non-copyable but swappable. +*/ +template< class T, class Deleter = ADLMIDI_DefaultDelete<T> > +class AdlMIDI_UPtr +{ + T *m_p; +public: + explicit AdlMIDI_UPtr(T *p) + : m_p(p) {} + ~AdlMIDI_UPtr() + { + reset(); + } + + void reset(T *p = NULL) + { + if(p != m_p) { + if(m_p) { + Deleter del; + del(m_p); + } + m_p = p; + } + } + + void swap(AdlMIDI_UPtr &other) + { + std::swap(m_p, other.m_p); + } + + T *get() const + { + return m_p; + } + T &operator*() const + { + return *m_p; + } + T *operator->() const + { + return m_p; + } + T &operator[](size_t index) const + { + return m_p[index]; + } +private: + AdlMIDI_UPtr(const AdlMIDI_UPtr &); + AdlMIDI_UPtr &operator=(const AdlMIDI_UPtr &); +}; + +template <class T> +void swap(AdlMIDI_UPtr<T> &a, AdlMIDI_UPtr<T> &b) +{ + a.swap(b); +} + +/** + Unique pointer for arrays. + */ +template<class T> +class AdlMIDI_UPtrArray : + public AdlMIDI_UPtr< T, ADLMIDI_DefaultArrayDelete<T> > +{ +public: + explicit AdlMIDI_UPtrArray(T *p = NULL) + : AdlMIDI_UPtr< T, ADLMIDI_DefaultArrayDelete<T> >(p) {} +}; + +/** + Unique pointer for C memory. + */ +template<class T> +class AdlMIDI_CPtr : + public AdlMIDI_UPtr< T, ADLMIDI_CDelete > +{ +public: + explicit AdlMIDI_CPtr(T *p = NULL) + : AdlMIDI_UPtr< T, ADLMIDI_CDelete >(p) {} +}; + +/* + Shared pointer with non-atomic counter + FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it +*/ +template< class T, class Deleter = ADLMIDI_DefaultDelete<T> > +class AdlMIDI_SPtr +{ + T *m_p; + size_t *m_counter; +public: + explicit AdlMIDI_SPtr(T *p = NULL) + : m_p(p), m_counter(p ? new size_t(1) : NULL) {} + ~AdlMIDI_SPtr() + { + reset(NULL); + } + + AdlMIDI_SPtr(const AdlMIDI_SPtr &other) + : m_p(other.m_p), m_counter(other.m_counter) + { + if(m_counter) + ++*m_counter; + } + + AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other) + { + if(this == &other) + return *this; + reset(); + m_p = other.m_p; + m_counter = other.m_counter; + if(m_counter) + ++*m_counter; + return *this; + } + + void reset(T *p = NULL) + { + if(p != m_p) { + if(m_p && --*m_counter == 0) { + Deleter del; + del(m_p); + if(!p) { + delete m_counter; + m_counter = NULL; + } + } + m_p = p; + if(p) { + if(!m_counter) + m_counter = new size_t; + *m_counter = 1; + } + } + } + + T *get() const + { + return m_p; + } + T &operator*() const + { + return *m_p; + } + T *operator->() const + { + return m_p; + } + T &operator[](size_t index) const + { + return m_p[index]; + } +}; + +/** + Shared pointer for arrays. + */ +template<class T> +class AdlMIDI_SPtrArray : + public AdlMIDI_SPtr< T, ADLMIDI_DefaultArrayDelete<T> > +{ +public: + explicit AdlMIDI_SPtrArray(T *p = NULL) + : AdlMIDI_SPtr< T, ADLMIDI_DefaultArrayDelete<T> >(p) {} +}; + +#endif //ADLMIDI_PTR_HPP_THING diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp index 3e21772..7d78c5f 100644 --- a/src/chips/dosbox/dbopl.cpp +++ b/src/chips/dosbox/dbopl.cpp @@ -1,10 +1,5 @@ -//#ifdef ADLMIDI_USE_DOSBOX_OPL - -#ifdef __MINGW32__ -typedef struct vswprintf {} swprintf; -#endif /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2018 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,22 +17,21 @@ typedef struct vswprintf {} swprintf; */ /* - DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator. - Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2 - Except for the table generation it's all integer math - Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms - The generation was based on the MAME implementation but tried to have it use less memory and be faster in general - MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times - - //TODO Don't delay first operator 1 sample in opl3 mode - //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter - //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? - //TODO Check if having the same accuracy in all frequency multipliers sounds better or not - - //DUNNO Keyon in 4op, switch to 2op without keyoff. + DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator. + Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2 + Except for the table generation it's all integer math + Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms + The generation was based on the MAME implementation but tried to have it use less memory and be faster in general + MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times + + //TODO Don't delay first operator 1 sample in opl3 mode + //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter + //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? + //TODO Check if having the same accuracy in all frequency multipliers sounds better or not + + //DUNNO Keyon in 4op, switch to 2op without keyoff. */ -/* $Id: dbopl.cpp,v 1.10 2009-06-10 19:54:51 harekiet Exp $ */ #include <math.h> @@ -45,2001 +39,1580 @@ typedef struct vswprintf {} swprintf; #include <string.h> #include "dbopl.h" -#define DB_MAX(x, y) ((x) > (y) ? (x) : (y)) -#define DB_MIN(x, y) ((x) < (y) ? (x) : (y)) +#if defined(__GNUC__) && __GNUC__ > 3 +#define INLINE inline __attribute__((__always_inline__)) +#elif defined(_MSC_VER) +#define INLINE __forceinline +#else +#define INLINE inline +#endif -#define DBOPL_CLAMP(V, MIN, MAX) DB_MAX(DB_MIN(V, (MAX)), (MIN)) +#if defined(__GNUC__) +#if !defined(__clang__) +#define GCC_LIKELY(x) __builtin_expect(x, 1) +#define GCC_UNLIKELY(x) __builtin_expect(x, 0) +#else // !defined(__clang__) +#if !defined (__c2__) && defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define GCC_LIKELY(x) __builtin_expect(x, 1) +#define GCC_UNLIKELY(x) __builtin_expect(x, 0) +#endif // __has_builtin(__builtin_expect) +#endif // !defined (__c2__) && defined(__has_builtin) +#endif // !defined(__clang__) +#endif // defined(__GNUC__) + +#if !defined(GCC_LIKELY) +#define GCC_LIKELY(x) (x) +#define GCC_UNLIKELY(x) (x) +#endif #ifndef PI #define PI 3.14159265358979323846 #endif -namespace DBOPL -{ +namespace DBOPL { -#define OPLRATE ((double)(14318180.0 / 288.0)) +#define OPLRATE ((double)(14318180.0 / 288.0)) #define TREMOLO_TABLE 52 - //Try to use most precision for frequencies - //Else try to keep different waves in synch - //#define WAVE_PRECISION 1 - #ifndef WAVE_PRECISION - //Wave bits available in the top of the 32bit range - //Original adlib uses 10.10, we use 10.22 -#define WAVE_BITS 10 - #else - //Need some extra bits at the top to have room for octaves and frequency multiplier - //We support to 8 times lower rate - //128 * 15 * 8 = 15350, 2^13.9, so need 14 bits -#define WAVE_BITS 14 - #endif -#define WAVE_SH ( 32 - WAVE_BITS ) -#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) - - //Use the same accuracy as the waves +//Try to use most precision for frequencies +//Else try to keep different waves in synch +//#define WAVE_PRECISION 1 +#ifndef WAVE_PRECISION +//Wave bits available in the top of the 32bit range +//Original adlib uses 10.10, we use 10.22 +#define WAVE_BITS 10 +#else +//Need some extra bits at the top to have room for octaves and frequency multiplier +//We support to 8 times lower rate +//128 * 15 * 8 = 15350, 2^13.9, so need 14 bits +#define WAVE_BITS 14 +#endif +#define WAVE_SH ( 32 - WAVE_BITS ) +#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) + +//Use the same accuracy as the waves #define LFO_SH ( WAVE_SH - 10 ) - //LFO is controlled by our tremolo 256 sample limit +//LFO is controlled by our tremolo 256 sample limit #define LFO_MAX ( 256 << ( LFO_SH ) ) - //Maximum amount of attenuation bits - //Envelope goes to 511, 9 bits - #if (DBOPL_WAVE == WAVE_TABLEMUL ) - //Uses the value directly -#define ENV_BITS ( 9 ) - #else - //Add 3 bits here for more accuracy and would have to be shifted up either way -#define ENV_BITS ( 9 ) - #endif - //Limits of the envelope with those bits and when the envelope goes silent -#define ENV_MIN 0 -#define ENV_EXTRA ( ENV_BITS - 9 ) -#define ENV_MAX ( 511 << ENV_EXTRA ) -#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) ) +//Maximum amount of attenuation bits +//Envelope goes to 511, 9 bits +#if (DBOPL_WAVE == WAVE_TABLEMUL ) +//Uses the value directly +#define ENV_BITS ( 9 ) +#else +//Add 3 bits here for more accuracy and would have to be shifted up either way +#define ENV_BITS ( 9 ) +#endif +//Limits of the envelope with those bits and when the envelope goes silent +#define ENV_MIN 0 +#define ENV_EXTRA ( ENV_BITS - 9 ) +#define ENV_MAX ( 511 << ENV_EXTRA ) +#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) ) #define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT ) - //Attack/decay/release rate counter shift -#define RATE_SH 24 -#define RATE_MASK ( ( 1 << RATE_SH ) - 1 ) - //Has to fit within 16bit lookuptable -#define MUL_SH 16 +//Attack/decay/release rate counter shift +#define RATE_SH 24 +#define RATE_MASK ( ( 1 << RATE_SH ) - 1 ) +//Has to fit within 16bit lookuptable +#define MUL_SH 16 - //Check some ranges - #if ENV_EXTRA > 3 +//Check some ranges +#if ENV_EXTRA > 3 #error Too many envelope bits - #endif +#endif - //How much to substract from the base value for the final attenuation - static const Bit8u KslCreateTable[16] = - { - //0 will always be be lower than 7 * 8 - 64, 32, 24, 19, - 16, 12, 11, 10, - 8, 6, 5, 4, - 3, 2, 1, 0, - }; +//How much to substract from the base value for the final attenuation +static const Bit8u KslCreateTable[16] = { + //0 will always be be lower than 7 * 8 + 64, 32, 24, 19, + 16, 12, 11, 10, + 8, 6, 5, 4, + 3, 2, 1, 0, +}; #define M(_X_) ((Bit8u)( (_X_) * 2)) - static const Bit8u FreqCreateTable[16] = - { - M(0.5), M(1), M(2), M(3), M(4), M(5), M(6), M(7), - M(8), M(9), M(10), M(10), M(12), M(12), M(15), M(15) - }; +static const Bit8u FreqCreateTable[16] = { + M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ), + M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15) +}; #undef M - //We're not including the highest attack rate, that gets a special value - static const Bit8u AttackSamplesTable[13] = - { - 69, 55, 46, 40, - 35, 29, 23, 20, - 19, 15, 11, 10, - 9 - }; - //On a real opl these values take 8 samples to reach and are based upon larger tables - static const Bit8u EnvelopeIncreaseTable[13] = - { - 4, 5, 6, 7, - 8, 10, 12, 14, - 16, 20, 24, 28, - 32, - }; - - #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) - static Bit16u ExpTable[ 256 ]; - #endif - - #if ( DBOPL_WAVE == WAVE_HANDLER ) - //PI table used by WAVEHANDLER - static Bit16u SinTable[ 512 ]; - #endif - - #if ( DBOPL_WAVE > WAVE_HANDLER ) - //Layout of the waveform table in 512 entry intervals - //With overlapping waves we reduce the table to half it's size - - // | |//\\|____|WAV7|//__|/\ |____|/\/\| - // |\\//| | |WAV7| | \/| | | - // |06 |0126|17 |7 |3 |4 |4 5 |5 | - - //6 is just 0 shifted and masked - - static Bit16s WaveTable[ 8 * 512 ]; - //Distance into WaveTable the wave starts - static const Bit16u WaveBaseTable[8] = - { - 0x000, 0x200, 0x200, 0x800, - 0xa00, 0xc00, 0x100, 0x400, - - }; - //Mask the counter with this - static const Bit16u WaveMaskTable[8] = - { - 1023, 1023, 511, 511, - 1023, 1023, 512, 1023, - }; - - //Where to start the counter on at keyon - static const Bit16u WaveStartTable[8] = - { - 512, 0, 0, 0, - 0, 512, 512, 256, - }; - #endif - - #if ( DBOPL_WAVE == WAVE_TABLEMUL ) - static Bit16u MulTable[ 384 ]; - #endif - - static Bit8u KslTable[ 8 * 16 ]; - static Bit8u TremoloTable[ TREMOLO_TABLE ]; - //Start of a channel behind the chip struct start - static Bit16u ChanOffsetTable[32]; - //Start of an operator behind the chip struct start - static Bit16u OpOffsetTable[64]; - - //The lower bits are the shift of the operator vibrato value - //The highest bit is right shifted to generate -1 or 0 for negation - //So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0 - static const Bit8s VibratoTable[ 8 ] = - { - 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, - 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 - }; - - //Shift strength for the ksl value determined by ksl strength - static const Bit8u KslShiftTable[4] = - { - 31, 1, 2, 0 - }; - - //Generate a table index and table shift value using input value from a selected rate - static void EnvelopeSelect(Bit8u val, Bit8u &index, Bit8u &shift) - { - if(val < 13 * 4) //Rate 0 - 12 - { - shift = 12 - (val >> 2); - index = val & 3; - } - else if(val < 15 * 4) //rate 13 - 14 - { - shift = 0; - index = val - 12 * 4; - } - else //rate 15 and up - { - shift = 0; - index = 12; - } - } - - #if ( DBOPL_WAVE == WAVE_HANDLER ) - /* - Generate the different waveforms out of the sine/exponetial table using handlers - */ - static inline Bits MakeVolume(Bitu wave, Bitu volume) - { - Bitu total = wave + volume; - Bitu index = total & 0xff; - Bitu sig = ExpTable[ index ]; - Bitu exp = total >> 8; - #if 0 - - //Check if we overflow the 31 shift limit - if(exp >= 32) - LOG_MSG("WTF %d %d", total, exp); - - #endif - return (sig >> exp); - }; - - static Bits DB_FASTCALL WaveForm0(Bitu i, Bitu volume) - { - Bits neg = 0 - ((i >> 9) & 1); //Create ~0 or 0 - Bitu wave = SinTable[i & 511]; - return (MakeVolume(wave, volume) ^ neg) - neg; - } - static Bits DB_FASTCALL WaveForm1(Bitu i, Bitu volume) - { - Bit32u wave = SinTable[i & 511]; - wave |= (((i ^ 512) & 512) - 1) >> (32 - 12); - return MakeVolume(wave, volume); - } - static Bits DB_FASTCALL WaveForm2(Bitu i, Bitu volume) - { - Bitu wave = SinTable[i & 511]; - return MakeVolume(wave, volume); - } - static Bits DB_FASTCALL WaveForm3(Bitu i, Bitu volume) - { - Bitu wave = SinTable[i & 255]; - wave |= (((i ^ 256) & 256) - 1) >> (32 - 12); - return MakeVolume(wave, volume); - } - static Bits DB_FASTCALL WaveForm4(Bitu i, Bitu volume) - { - //Twice as fast - i <<= 1; - Bits neg = 0 - ((i >> 9) & 1); //Create ~0 or 0 - Bitu wave = SinTable[i & 511]; - wave |= (((i ^ 512) & 512) - 1) >> (32 - 12); - return (MakeVolume(wave, volume) ^ neg) - neg; - } - static Bits DB_FASTCALL WaveForm5(Bitu i, Bitu volume) - { - //Twice as fast - i <<= 1; - Bitu wave = SinTable[i & 511]; - wave |= (((i ^ 512) & 512) - 1) >> (32 - 12); - return MakeVolume(wave, volume); - } - static Bits DB_FASTCALL WaveForm6(Bitu i, Bitu volume) - { - Bits neg = 0 - ((i >> 9) & 1); //Create ~0 or 0 - return (MakeVolume(0, volume) ^ neg) - neg; - } - static Bits DB_FASTCALL WaveForm7(Bitu i, Bitu volume) - { - //Negative is reversed here - Bits neg = ((i >> 9) & 1) - 1; - Bitu wave = (i << 3); - //When negative the volume also runs backwards - wave = ((wave ^ neg) - neg) & 4095; - return (MakeVolume(wave, volume) ^ neg) - neg; - } - - static const WaveHandler WaveHandlerTable[8] = - { - WaveForm0, WaveForm1, WaveForm2, WaveForm3, - WaveForm4, WaveForm5, WaveForm6, WaveForm7 - }; - - #endif - - /* - Operator - */ - - //We zero out when rate == 0 - inline void Operator::UpdateAttack(const Chip *chip) - { - Bit8u rate = reg60 >> 4; - - if(rate) - { - Bit8u val = (rate << 2) + ksr; - attackAdd = chip->attackRates[ val ]; - rateZero &= ~(1 << ATTACK); - } - else - { - attackAdd = 0; - rateZero |= (1 << ATTACK); - } - } - inline void Operator::UpdateDecay(const Chip *chip) - { - Bit8u rate = reg60 & 0xf; - - if(rate) - { - Bit8u val = (rate << 2) + ksr; - decayAdd = chip->linearRates[ val ]; - rateZero &= ~(1 << DECAY); - } - else - { - decayAdd = 0; - rateZero |= (1 << DECAY); - } - } - inline void Operator::UpdateRelease(const Chip *chip) - { - Bit8u rate = reg80 & 0xf; - - if(rate) - { - Bit8u val = (rate << 2) + ksr; - releaseAdd = chip->linearRates[ val ]; - rateZero &= ~(1 << RELEASE); - - if(!(reg20 & MASK_SUSTAIN)) - rateZero &= ~(1 << SUSTAIN); - } - else - { - rateZero |= (1 << RELEASE); - releaseAdd = 0; - - if(!(reg20 & MASK_SUSTAIN)) - rateZero |= (1 << SUSTAIN); - } - } - - inline void Operator::UpdateAttenuation() - { - Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff); - Bit32u tl = reg40 & 0x3f; - Bit8u kslShift = KslShiftTable[ reg40 >> 6 ]; - //Make sure the attenuation goes to the right bits - totalLevel = tl << (ENV_BITS - 7); //Total level goes 2 bits below max - totalLevel += (kslBase << ENV_EXTRA) >> kslShift; - } - - void Operator::UpdateFrequency() - { - Bit32u freq = chanData & ((1 << 10) - 1); - Bit32u block = (chanData >> 10) & 0xff; - #ifdef WAVE_PRECISION - block = 7 - block; - waveAdd = (freq * freqMul) >> block; - #else - waveAdd = (freq << block) * freqMul; - #endif - - if(reg20 & MASK_VIBRATO) - { - vibStrength = (Bit8u)(freq >> 7); - #ifdef WAVE_PRECISION - vibrato = (vibStrength * freqMul) >> block; - #else - vibrato = (vibStrength << block) * freqMul; - #endif - } - else - { - vibStrength = 0; - vibrato = 0; - } - } - - void Operator::UpdateRates(const Chip *chip) - { - //Mame seems to reverse this where enabling ksr actually lowers - //the rate, but pdf manuals says otherwise? - Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff); - - if(!(reg20 & MASK_KSR)) - newKsr >>= 2; - - if(ksr == newKsr) - return; - - ksr = newKsr; - UpdateAttack(chip); - UpdateDecay(chip); - UpdateRelease(chip); - } - - INLINE Bit32s Operator::RateForward(Bit32u add) - { - rateIndex += add; - Bit32s ret = rateIndex >> RATE_SH; - rateIndex = rateIndex & RATE_MASK; - return ret; - } - - template< Operator::State yes> - Bits Operator::TemplateVolume() - { - Bit32s vol = volume; - Bit32s change; - - switch(yes) - { - case OFF: - return ENV_MAX; - - case ATTACK: - change = RateForward(attackAdd); - - if(!change) - return vol; - - vol += ((~vol) * change) >> 3; - - if(vol < ENV_MIN) - { - volume = ENV_MIN; - rateIndex = 0; - SetState(DECAY); - return ENV_MIN; - } - - break; - - case DECAY: - vol += RateForward(decayAdd); - - if(GCC_UNLIKELY(vol >= sustainLevel)) - { - //Check if we didn't overshoot max attenuation, then just go off - if(GCC_UNLIKELY(vol >= ENV_MAX)) - { - volume = ENV_MAX; - SetState(OFF); - return ENV_MAX; - } - - //Continue as sustain - rateIndex = 0; - SetState(SUSTAIN); - } - - break; - - case SUSTAIN: - if(reg20 & MASK_SUSTAIN) - return vol; - - //In sustain phase, but not sustaining, do regular release - case RELEASE: - vol += RateForward(releaseAdd);; - - if(GCC_UNLIKELY(vol >= ENV_MAX)) - { - volume = ENV_MAX; - SetState(OFF); - return ENV_MAX; - } - - break; - } - - volume = vol; - return vol; - } - - static const VolumeHandler VolumeHandlerTable[5] = - { - &Operator::TemplateVolume< Operator::OFF >, - &Operator::TemplateVolume< Operator::RELEASE >, - &Operator::TemplateVolume< Operator::SUSTAIN >, - &Operator::TemplateVolume< Operator::DECAY >, - &Operator::TemplateVolume< Operator::ATTACK > - }; - - INLINE Bitu Operator::ForwardVolume() - { - return currentLevel + (this->*volHandler)(); - } - - - INLINE Bitu Operator::ForwardWave() - { - waveIndex += waveCurrent; - return waveIndex >> WAVE_SH; - } - - void Operator::Write20(const Chip *chip, Bit8u val) - { - Bit8u change = (reg20 ^ val); - - if(!change) - return; - - reg20 = val; - //Shift the tremolo bit over the entire register, saved a branch, YES! - tremoloMask = (Bit8s)(val) >> 7; - tremoloMask &= ~((1 << ENV_EXTRA) - 1); - - //Update specific features based on changes - if(change & MASK_KSR) - UpdateRates(chip); - - //With sustain enable the volume doesn't change - if(reg20 & MASK_SUSTAIN || (!releaseAdd)) - rateZero |= (1 << SUSTAIN); - else - rateZero &= ~(1 << SUSTAIN); - - //Frequency multiplier or vibrato changed - if(change & (0xf | MASK_VIBRATO)) - { - freqMul = chip->freqMul[ val & 0xf ]; - UpdateFrequency(); - } - } - - void Operator::Write40(const Chip * /*chip*/, Bit8u val) - { - if(!(reg40 ^ val)) - return; - - reg40 = val; - UpdateAttenuation(); - } - - void Operator::Write60(const Chip *chip, Bit8u val) - { - Bit8u change = reg60 ^ val; - reg60 = val; - - if(change & 0x0f) - UpdateDecay(chip); - - if(change & 0xf0) - UpdateAttack(chip); - } - - void Operator::Write80(const Chip *chip, Bit8u val) - { - Bit8u change = (reg80 ^ val); - - if(!change) - return; - - reg80 = val; - Bit8u sustain = val >> 4; - //Turn 0xf into 0x1f - sustain |= (sustain + 1) & 0x10; - sustainLevel = sustain << (ENV_BITS - 5); - - if(change & 0x0f) - UpdateRelease(chip); - } - - void Operator::WriteE0(const Chip *chip, Bit8u val) - { - if(!(regE0 ^ val)) - return; - - //in opl3 mode you can always selet 7 waveforms regardless of waveformselect - Bit8u waveForm = val & ((0x3 & chip->waveFormMask) | (0x7 & chip->opl3Active)); - regE0 = val; - #if ( DBOPL_WAVE == WAVE_HANDLER ) - waveHandler = WaveHandlerTable[ waveForm ]; - #else - waveBase = WaveTable + WaveBaseTable[ waveForm ]; - waveStart = WaveStartTable[ waveForm ] << WAVE_SH; - waveMask = WaveMaskTable[ waveForm ]; - #endif - } - - INLINE void Operator::SetState(Bit8u s) - { - state = s; - volHandler = VolumeHandlerTable[ s ]; - } - - INLINE bool Operator::Silent() const - { - if(!ENV_SILENT(totalLevel + volume)) - return false; - - if(!(rateZero & (1 << state))) - return false; - - return true; - } - - INLINE void Operator::Prepare(const Chip *chip) - { - currentLevel = totalLevel + (chip->tremoloValue & tremoloMask); - waveCurrent = waveAdd; - - if(vibStrength >> chip->vibratoShift) - { - Bit32s add = vibrato >> chip->vibratoShift; - //Sign extend over the shift value - Bit32s neg = chip->vibratoSign; - //Negate the add with -1 or 0 - add = (add ^ neg) - neg; - waveCurrent += add; - } - } - - void Operator::KeyOn(Bit8u mask) - { - if(!keyOn) - { - //Restart the frequency generator - #if ( DBOPL_WAVE > WAVE_HANDLER ) - waveIndex = waveStart; - #else - waveIndex = 0; - #endif - rateIndex = 0; - SetState(ATTACK); - } - - keyOn |= mask; - } - - void Operator::KeyOff(Bit8u mask) - { - keyOn &= ~mask; - - if(!keyOn) - { - if(state != OFF) - SetState(RELEASE); - } - } - - INLINE Bits Operator::GetWave(Bitu index, Bitu vol) - { - #if ( DBOPL_WAVE == WAVE_HANDLER ) - return waveHandler(index, vol << (3 - ENV_EXTRA)); - #elif ( DBOPL_WAVE == WAVE_TABLEMUL ) - return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; - #elif ( DBOPL_WAVE == WAVE_TABLELOG ) - Bit32s wave = waveBase[ index & waveMask ]; - Bit32u total = (wave & 0x7fff) + vol << (3 - ENV_EXTRA); - Bit32s sig = ExpTable[ total & 0xff ]; - Bit32u exp = total >> 8; - Bit32s neg = wave >> 16; - return ((sig ^ neg) - neg) >> exp; - #else +//We're not including the highest attack rate, that gets a special value +static const Bit8u AttackSamplesTable[13] = { + 69, 55, 46, 40, + 35, 29, 23, 20, + 19, 15, 11, 10, + 9 +}; +//On a real opl these values take 8 samples to reach and are based upon larger tables +static const Bit8u EnvelopeIncreaseTable[13] = { + 4, 5, 6, 7, + 8, 10, 12, 14, + 16, 20, 24, 28, + 32, +}; + +#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) +static Bit16u ExpTable[ 256 ]; +#endif + +#if ( DBOPL_WAVE == WAVE_HANDLER ) +//PI table used by WAVEHANDLER +static Bit16u SinTable[ 512 ]; +#endif + +#if ( DBOPL_WAVE > WAVE_HANDLER ) +//Layout of the waveform table in 512 entry intervals +//With overlapping waves we reduce the table to half it's size + +// | |//\\|____|WAV7|//__|/\ |____|/\/\| +// |\\//| | |WAV7| | \/| | | +// |06 |0126|17 |7 |3 |4 |4 5 |5 | + +//6 is just 0 shifted and masked + +static Bit16s WaveTable[ 8 * 512 ]; +//Distance into WaveTable the wave starts +static const Bit16u WaveBaseTable[8] = { + 0x000, 0x200, 0x200, 0x800, + 0xa00, 0xc00, 0x100, 0x400, + +}; +//Mask the counter with this +static const Bit16u WaveMaskTable[8] = { + 1023, 1023, 511, 511, + 1023, 1023, 512, 1023, +}; + +//Where to start the counter on at keyon +static const Bit16u WaveStartTable[8] = { + 512, 0, 0, 0, + 0, 512, 512, 256, +}; +#endif + +#if ( DBOPL_WAVE == WAVE_TABLEMUL ) +static Bit16u MulTable[ 384 ]; +#endif + +static Bit8u KslTable[ 8 * 16 ]; +static Bit8u TremoloTable[ TREMOLO_TABLE ]; +//Start of a channel behind the chip struct start +static Bit16u ChanOffsetTable[32]; +//Start of an operator behind the chip struct start +static Bit16u OpOffsetTable[64]; + +//The lower bits are the shift of the operator vibrato value +//The highest bit is right shifted to generate -1 or 0 for negation +//So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0 +static const Bit8s VibratoTable[ 8 ] = { + 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, + 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 +}; + +//Shift strength for the ksl value determined by ksl strength +static const Bit8u KslShiftTable[4] = { + 31,1,2,0 +}; + +//Generate a table index and table shift value using input value from a selected rate +static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) { + if ( val < 13 * 4 ) { //Rate 0 - 12 + shift = 12 - ( val >> 2 ); + index = val & 3; + } else if ( val < 15 * 4 ) { //rate 13 - 14 + shift = 0; + index = val - 12 * 4; + } else { //rate 15 and up + shift = 0; + index = 12; + } +} + +#if ( DBOPL_WAVE == WAVE_HANDLER ) +/* + Generate the different waveforms out of the sine/exponetial table using handlers +*/ +static inline Bits MakeVolume( Bitu wave, Bitu volume ) { + Bitu total = wave + volume; + Bitu index = total & 0xff; + Bitu sig = ExpTable[ index ]; + Bitu exp = total >> 8; +#if 0 + //Check if we overflow the 31 shift limit + if ( exp >= 32 ) { + LOG_MSG( "WTF %d %d", total, exp ); + } +#endif + return (sig >> exp); +}; + +static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) { + Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 + Bitu wave = SinTable[i & 511]; + return (MakeVolume( wave, volume ) ^ neg) - neg; +} +static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) { + Bit32u wave = SinTable[i & 511]; + wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); + return MakeVolume( wave, volume ); +} +static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) { + Bitu wave = SinTable[i & 511]; + return MakeVolume( wave, volume ); +} +static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) { + Bitu wave = SinTable[i & 255]; + wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 ); + return MakeVolume( wave, volume ); +} +static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) { + //Twice as fast + i <<= 1; + Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 + Bitu wave = SinTable[i & 511]; + wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); + return (MakeVolume( wave, volume ) ^ neg) - neg; +} +static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) { + //Twice as fast + i <<= 1; + Bitu wave = SinTable[i & 511]; + wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); + return MakeVolume( wave, volume ); +} +static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) { + Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 + return (MakeVolume( 0, volume ) ^ neg) - neg; +} +static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) { + //Negative is reversed here + Bits neg = (( i >> 9) & 1) - 1; + Bitu wave = (i << 3); + //When negative the volume also runs backwards + wave = ((wave ^ neg) - neg) & 4095; + return (MakeVolume( wave, volume ) ^ neg) - neg; +} + +static const WaveHandler WaveHandlerTable[8] = { + WaveForm0, WaveForm1, WaveForm2, WaveForm3, + WaveForm4, WaveForm5, WaveForm6, WaveForm7 +}; + +#endif + +/* + Operator +*/ + +//We zero out when rate == 0 +inline void Operator::UpdateAttack( const Chip* chip ) { + Bit8u rate = reg60 >> 4; + if ( rate ) { + Bit8u val = (rate << 2) + ksr; + attackAdd = chip->attackRates[ val ]; + rateZero &= ~(1 << ATTACK); + } else { + attackAdd = 0; + rateZero |= (1 << ATTACK); + } +} +inline void Operator::UpdateDecay( const Chip* chip ) { + Bit8u rate = reg60 & 0xf; + if ( rate ) { + Bit8u val = (rate << 2) + ksr; + decayAdd = chip->linearRates[ val ]; + rateZero &= ~(1 << DECAY); + } else { + decayAdd = 0; + rateZero |= (1 << DECAY); + } +} +inline void Operator::UpdateRelease( const Chip* chip ) { + Bit8u rate = reg80 & 0xf; + if ( rate ) { + Bit8u val = (rate << 2) + ksr; + releaseAdd = chip->linearRates[ val ]; + rateZero &= ~(1 << RELEASE); + if ( !(reg20 & MASK_SUSTAIN ) ) { + rateZero &= ~( 1 << SUSTAIN ); + } + } else { + rateZero |= (1 << RELEASE); + releaseAdd = 0; + if ( !(reg20 & MASK_SUSTAIN ) ) { + rateZero |= ( 1 << SUSTAIN ); + } + } +} + +inline void Operator::UpdateAttenuation( ) { + Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff); + Bit32u tl = reg40 & 0x3f; + Bit8u kslShift = KslShiftTable[ reg40 >> 6 ]; + //Make sure the attenuation goes to the right bits + totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max + totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift; +} + +void Operator::UpdateFrequency( ) { + Bit32u freq = chanData & (( 1 << 10 ) - 1); + Bit32u block = (chanData >> 10) & 0xff; +#ifdef WAVE_PRECISION + block = 7 - block; + waveAdd = ( freq * freqMul ) >> block; +#else + waveAdd = ( freq << block ) * freqMul; +#endif + if ( reg20 & MASK_VIBRATO ) { + vibStrength = (Bit8u)(freq >> 7); + +#ifdef WAVE_PRECISION + vibrato = ( vibStrength * freqMul ) >> block; +#else + vibrato = ( vibStrength << block ) * freqMul; +#endif + } else { + vibStrength = 0; + vibrato = 0; + } +} + +void Operator::UpdateRates( const Chip* chip ) { + //Mame seems to reverse this where enabling ksr actually lowers + //the rate, but pdf manuals says otherwise? + Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff); + if ( !( reg20 & MASK_KSR ) ) { + newKsr >>= 2; + } + if ( ksr == newKsr ) + return; + ksr = newKsr; + UpdateAttack( chip ); + UpdateDecay( chip ); + UpdateRelease( chip ); +} + +INLINE Bit32s Operator::RateForward( Bit32u add ) { + rateIndex += add; + Bit32s ret = rateIndex >> RATE_SH; + rateIndex = rateIndex & RATE_MASK; + return ret; +} + +template< Operator::State yes> +Bits Operator::TemplateVolume( ) { + Bit32s vol = volume; + Bit32s change; + switch ( yes ) { + case OFF: + return ENV_MAX; + case ATTACK: + change = RateForward( attackAdd ); + if ( !change ) + return vol; + vol += ( (~vol) * change ) >> 3; + if ( vol < ENV_MIN ) { + volume = ENV_MIN; + rateIndex = 0; + SetState( DECAY ); + return ENV_MIN; + } + break; + case DECAY: + vol += RateForward( decayAdd ); + if ( GCC_UNLIKELY(vol >= sustainLevel) ) { + //Check if we didn't overshoot max attenuation, then just go off + if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { + volume = ENV_MAX; + SetState( OFF ); + return ENV_MAX; + } + //Continue as sustain + rateIndex = 0; + SetState( SUSTAIN ); + } + break; + case SUSTAIN: + if ( reg20 & MASK_SUSTAIN ) { + return vol; + } + //In sustain phase, but not sustaining, do regular release + case RELEASE: + vol += RateForward( releaseAdd );; + if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { + volume = ENV_MAX; + SetState( OFF ); + return ENV_MAX; + } + break; + } + volume = vol; + return vol; +} + +static const VolumeHandler VolumeHandlerTable[5] = { + &Operator::TemplateVolume< Operator::OFF >, + &Operator::TemplateVolume< Operator::RELEASE >, + &Operator::TemplateVolume< Operator::SUSTAIN >, + &Operator::TemplateVolume< Operator::DECAY >, + &Operator::TemplateVolume< Operator::ATTACK > +}; + +INLINE Bitu Operator::ForwardVolume() { + return currentLevel + (this->*volHandler)(); +} + + +INLINE Bitu Operator::ForwardWave() { + waveIndex += waveCurrent; + return waveIndex >> WAVE_SH; +} + +void Operator::Write20( const Chip* chip, Bit8u val ) { + Bit8u change = (reg20 ^ val ); + if ( !change ) + return; + reg20 = val; + //Shift the tremolo bit over the entire register, saved a branch, YES! + tremoloMask = (Bit8s)(val) >> 7; + tremoloMask &= ~(( 1 << ENV_EXTRA ) -1); + //Update specific features based on changes + if ( change & MASK_KSR ) { + UpdateRates( chip ); + } + //With sustain enable the volume doesn't change + if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) { + rateZero |= ( 1 << SUSTAIN ); + } else { + rateZero &= ~( 1 << SUSTAIN ); + } + //Frequency multiplier or vibrato changed + if ( change & (0xf | MASK_VIBRATO) ) { + freqMul = chip->freqMul[ val & 0xf ]; + UpdateFrequency(); + } +} + +void Operator::Write40( const Chip* /*chip*/, Bit8u val ) { + if (!(reg40 ^ val )) + return; + reg40 = val; + UpdateAttenuation( ); +} + +void Operator::Write60( const Chip* chip, Bit8u val ) { + Bit8u change = reg60 ^ val; + reg60 = val; + if ( change & 0x0f ) { + UpdateDecay( chip ); + } + if ( change & 0xf0 ) { + UpdateAttack( chip ); + } +} + +void Operator::Write80( const Chip* chip, Bit8u val ) { + Bit8u change = (reg80 ^ val ); + if ( !change ) + return; + reg80 = val; + Bit8u sustain = val >> 4; + //Turn 0xf into 0x1f + sustain |= ( sustain + 1) & 0x10; + sustainLevel = sustain << ( ENV_BITS - 5 ); + if ( change & 0x0f ) { + UpdateRelease( chip ); + } +} + +void Operator::WriteE0( const Chip* chip, Bit8u val ) { + if ( !(regE0 ^ val) ) + return; + //in opl3 mode you can always selet 7 waveforms regardless of waveformselect + Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) ); + regE0 = val; +#if ( DBOPL_WAVE == WAVE_HANDLER ) + waveHandler = WaveHandlerTable[ waveForm ]; +#else + waveBase = WaveTable + WaveBaseTable[ waveForm ]; + waveStart = WaveStartTable[ waveForm ] << WAVE_SH; + waveMask = WaveMaskTable[ waveForm ]; +#endif +} + +INLINE void Operator::SetState( Bit8u s ) { + state = s; + volHandler = VolumeHandlerTable[ s ]; +} + +INLINE bool Operator::Silent() const { + if ( !ENV_SILENT( totalLevel + volume ) ) + return false; + if ( !(rateZero & ( 1 << state ) ) ) + return false; + return true; +} + +INLINE void Operator::Prepare( const Chip* chip ) { + currentLevel = totalLevel + (chip->tremoloValue & tremoloMask); + waveCurrent = waveAdd; + if ( vibStrength >> chip->vibratoShift ) { + Bit32s add = vibrato >> chip->vibratoShift; + //Sign extend over the shift value + Bit32s neg = chip->vibratoSign; + //Negate the add with -1 or 0 + add = ( add ^ neg ) - neg; + waveCurrent += add; + } +} + +void Operator::KeyOn( Bit8u mask ) { + if ( !keyOn ) { + //Restart the frequency generator +#if ( DBOPL_WAVE > WAVE_HANDLER ) + waveIndex = waveStart; +#else + waveIndex = 0; +#endif + rateIndex = 0; + SetState( ATTACK ); + } + keyOn |= mask; +} + +void Operator::KeyOff( Bit8u mask ) { + keyOn &= ~mask; + if ( !keyOn ) { + if ( state != OFF ) { + SetState( RELEASE ); + } + } +} + +INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) { +#if ( DBOPL_WAVE == WAVE_HANDLER ) + return waveHandler( index, vol << ( 3 - ENV_EXTRA ) ); +#elif ( DBOPL_WAVE == WAVE_TABLEMUL ) + return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; +#elif ( DBOPL_WAVE == WAVE_TABLELOG ) + Bit32s wave = waveBase[ index & waveMask ]; + Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA ); + Bit32s sig = ExpTable[ total & 0xff ]; + Bit32u exp = total >> 8; + Bit32s neg = wave >> 16; + return ((sig ^ neg) - neg) >> exp; +#else #error "No valid wave routine" - #endif - } - - Bits INLINE Operator::GetSample(Bits modulation) - { - Bitu vol = ForwardVolume(); - - if(ENV_SILENT(vol)) - { - //Simply forward the wave - waveIndex += waveCurrent; - return 0; - } - else - { - Bitu index = ForwardWave(); - index += modulation; - return GetWave(index, vol); - } - } - - Operator::Operator() - { - chanData = 0; - freqMul = 0; - waveIndex = 0; - waveAdd = 0; - waveCurrent = 0; - keyOn = 0; - ksr = 0; - reg20 = 0; - reg40 = 0; - reg60 = 0; - reg80 = 0; - regE0 = 0; - SetState(OFF); - rateZero = (1 << OFF); - sustainLevel = ENV_MAX; - currentLevel = ENV_MAX; - totalLevel = ENV_MAX; - volume = ENV_MAX; - releaseAdd = 0; - } - - /* - Channel - */ - - Channel::Channel() - { - old[0] = old[1] = 0; - chanData = 0; - regB0 = 0; - regC0 = 0; - maskLeft = -1; - maskRight = -1; - feedback = 31; - fourMask = 0; - synthHandler = &Channel::BlockTemplate< sm2FM >; - } - - void Channel::SetChanData(const Chip *chip, Bit32u data) - { - Bit32u change = chanData ^ data; - chanData = data; - Op(0)->chanData = data; - Op(1)->chanData = data; - //Since a frequency update triggered this, always update frequency - Op(0)->UpdateFrequency(); - Op(1)->UpdateFrequency(); - - if(change & (0xff << SHIFT_KSLBASE)) - { - Op(0)->UpdateAttenuation(); - Op(1)->UpdateAttenuation(); - } - - if(change & (0xff << SHIFT_KEYCODE)) - { - Op(0)->UpdateRates(chip); - Op(1)->UpdateRates(chip); - } - } - - void Channel::UpdateFrequency(const Chip *chip, Bit8u fourOp) - { - //Extrace the frequency bits - Bit32u data = chanData & 0xffff; - Bit32u kslBase = KslTable[ data >> 6 ]; - Bit32u keyCode = (data & 0x1c00) >> 9; - - if(chip->reg08 & 0x40) - { - keyCode |= (data & 0x100) >> 8; /* notesel == 1 */ - } - else - { - keyCode |= (data & 0x200) >> 9; /* notesel == 0 */ - } - - //Add the keycode and ksl into the highest bits of chanData - data |= (keyCode << SHIFT_KEYCODE) | (kslBase << SHIFT_KSLBASE); - (this + 0)->SetChanData(chip, data); - - if(fourOp & 0x3f) - (this + 1)->SetChanData(chip, data); - } - - void Channel::WriteA0(const Chip *chip, Bit8u val) - { - Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; - - //Don't handle writes to silent fourop channels - if(fourOp > 0x80) - return; - - Bit32u change = (chanData ^ val) & 0xff; - - if(change) - { - chanData ^= change; - UpdateFrequency(chip, fourOp); - } - } - - void Channel::WriteB0(const Chip *chip, Bit8u val) - { - Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; - - //Don't handle writes to silent fourop channels - if(fourOp > 0x80) - return; - - Bitu change = (chanData ^ (val << 8)) & 0x1f00; - - if(change) - { - chanData ^= change; - UpdateFrequency(chip, fourOp); - } - - //Check for a change in the keyon/off state - if(!((val ^ regB0) & 0x20)) - return; - - regB0 = val; - - if(val & 0x20) - { - Op(0)->KeyOn(0x1); - Op(1)->KeyOn(0x1); - - if(fourOp & 0x3f) - { - (this + 1)->Op(0)->KeyOn(1); - (this + 1)->Op(1)->KeyOn(1); - } - } - else - { - Op(0)->KeyOff(0x1); - Op(1)->KeyOff(0x1); - - if(fourOp & 0x3f) - { - (this + 1)->Op(0)->KeyOff(1); - (this + 1)->Op(1)->KeyOff(1); - } - } - } - - void Channel::WriteC0(const Chip *chip, Bit8u val) - { - Bit8u change = val ^ regC0; - - if(!change) - return; - - regC0 = val; - feedback = (val >> 1) & 7; - - if(feedback) - { - //We shift the input to the right 10 bit wave index value - feedback = 9 - feedback; - } - else - feedback = 31; - - //Select the new synth mode - if(chip->opl3Active) - { - //4-op mode enabled for this channel - if((chip->reg104 & fourMask) & 0x3f) - { - Channel *chan0, *chan1; - - //Check if it's the 2nd channel in a 4-op - if(!(fourMask & 0x80)) - { - chan0 = this; - chan1 = this + 1; - } - else - { - chan0 = this - 1; - chan1 = this; - } - - Bit8u synth = ((chan0->regC0 & 1) << 0) | ((chan1->regC0 & 1) << 1); - - switch(synth) - { - case 0: - chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >; - break; - - case 1: - chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >; - break; - - case 2: - chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >; - break; - - case 3: - chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; - break; - } - - //Disable updating percussion channels - } - else if((fourMask & 0x40) && (chip->regBD & 0x20)) - { - //Regular dual op, am or fm - } - else if(val & 1) - synthHandler = &Channel::BlockTemplate< sm3AM >; - else - synthHandler = &Channel::BlockTemplate< sm3FM >; - - maskLeft = (val & 0x10) ? -1 : 0; - maskRight = (val & 0x20) ? -1 : 0; - //opl2 active - } - else - { - //Disable updating percussion channels - if((fourMask & 0x40) && (chip->regBD & 0x20)) - { - //Regular dual op, am or fm - } - else if(val & 1) - synthHandler = &Channel::BlockTemplate< sm2AM >; - else - synthHandler = &Channel::BlockTemplate< sm2FM >; - } - } - - void Channel::ResetC0(const Chip *chip) - { - Bit8u val = regC0; - regC0 ^= 0xff; - WriteC0(chip, val); - } - - template< bool opl3Mode> - INLINE void Channel::GeneratePercussion(Chip *chip, Bit32s *output) - { - Channel *chan = this; - //BassDrum - Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; - old[0] = old[1]; - old[1] = Op(0)->GetSample(mod); - - //When bassdrum is in AM mode first operator is ignoed - if(chan->regC0 & 1) - mod = 0; - else - mod = old[0]; - - Bit32s sample = Op(1)->GetSample(mod); - //Precalculate stuff used by other outputs - Bit32u noiseBit = chip->ForwardNoise() & 0x1; - Bit32u c2 = Op(2)->ForwardWave(); - Bit32u c5 = Op(5)->ForwardWave(); - Bit32u phaseBit = (((c2 & 0x88) ^ ((c2 << 5) & 0x80)) | ((c5 ^ (c5 << 2)) & 0x20)) ? 0x02 : 0x00; - //Hi-Hat - Bit32u hhVol = Op(2)->ForwardVolume(); - - if(!ENV_SILENT(hhVol)) - { - Bit32u hhIndex = (phaseBit << 8) | (0x34 << (phaseBit ^ (noiseBit << 1))); - sample += Op(2)->GetWave(hhIndex, hhVol); - } - - //Snare Drum - Bit32u sdVol = Op(3)->ForwardVolume(); - - if(!ENV_SILENT(sdVol)) - { - Bit32u sdIndex = (0x100 + (c2 & 0x100)) ^ (noiseBit << 8); - sample += Op(3)->GetWave(sdIndex, sdVol); - } - - //Tom-tom - sample += Op(4)->GetSample(0); - //Top-Cymbal - Bit32u tcVol = Op(5)->ForwardVolume(); - - if(!ENV_SILENT(tcVol)) - { - Bit32u tcIndex = (1 + phaseBit) << 8; - sample += Op(5)->GetWave(tcIndex, tcVol); - } - - sample <<= 1; - - if(opl3Mode) - { - output[0] += sample; - output[1] += sample; - } - else - output[0] += sample; - } - - template<SynthMode mode> - Channel *Channel::BlockTemplate(Chip *chip, Bit32u samples, Bit32s *output) - { - switch(mode) - { - case sm2AM: - case sm3AM: - if(Op(0)->Silent() && Op(1)->Silent()) - { - old[0] = old[1] = 0; - return (this + 1); - } - - break; - - case sm2FM: - case sm3FM: - if(Op(1)->Silent()) - { - old[0] = old[1] = 0; - return (this + 1); - } - - break; - - case sm3FMFM: - if(Op(3)->Silent()) - { - old[0] = old[1] = 0; - return (this + 2); - } - - break; - - case sm3AMFM: - if(Op(0)->Silent() && Op(3)->Silent()) - { - old[0] = old[1] = 0; - return (this + 2); - } - - break; - - case sm3FMAM: - if(Op(1)->Silent() && Op(3)->Silent()) - { - old[0] = old[1] = 0; - return (this + 2); - } - - break; - - case sm3AMAM: - if(Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent()) - { - old[0] = old[1] = 0; - return (this + 2); - } - - break; - - default: - break; - } - - //Init the operators with the the current vibrato and tremolo values - Op(0)->Prepare(chip); - Op(1)->Prepare(chip); - - if(mode > sm4Start) - { - Op(2)->Prepare(chip); - Op(3)->Prepare(chip); - } - - if(mode > sm6Start) - { - Op(4)->Prepare(chip); - Op(5)->Prepare(chip); - } - - for(Bitu i = 0; i < samples; i++) - { - //Early out for percussion handlers - if(mode == sm2Percussion) - { - GeneratePercussion<false>(chip, output + i); - continue; //Prevent some unitialized value bitching - } - else if(mode == sm3Percussion) - { - GeneratePercussion<true>(chip, output + i * 2); - continue; //Prevent some unitialized value bitching - } - - //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise - Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; - old[0] = old[1]; - old[1] = Op(0)->GetSample(mod); - Bit32s sample; - Bit32s out0 = old[0]; - - if(mode == sm2AM || mode == sm3AM) - sample = out0 + Op(1)->GetSample(0); - else if(mode == sm2FM || mode == sm3FM) - sample = Op(1)->GetSample(out0); - else if(mode == sm3FMFM) - { - Bits next = Op(1)->GetSample(out0); - next = Op(2)->GetSample(next); - sample = Op(3)->GetSample(next); - } - else if(mode == sm3AMFM) - { - sample = out0; - Bits next = Op(1)->GetSample(0); - next = Op(2)->GetSample(next); - sample += Op(3)->GetSample(next); - } - else if(mode == sm3FMAM) - { - sample = Op(1)->GetSample(out0); - Bits next = Op(2)->GetSample(0); - sample += Op(3)->GetSample(next); - } - else if(mode == sm3AMAM) - { - sample = out0; - Bits next = Op(1)->GetSample(0); - sample += Op(2)->GetSample(next); - sample += Op(3)->GetSample(0); - } - - switch(mode) - { - case sm2AM: - case sm2FM: - output[ i ] += sample; - break; - - case sm3AM: - case sm3FM: - case sm3FMFM: - case sm3AMFM: - case sm3FMAM: - case sm3AMAM: - output[ i * 2 + 0 ] += sample & maskLeft; - output[ i * 2 + 1 ] += sample & maskRight; - break; - - default: - break; - } - } - - switch(mode) - { - case sm2AM: - case sm2FM: - case sm3AM: - case sm3FM: - return (this + 1); - - case sm3FMFM: - case sm3AMFM: - case sm3FMAM: - case sm3AMAM: - return(this + 2); - - case sm2Percussion: - case sm3Percussion: - return(this + 3); - } - - return 0; - } - - /* - Chip - */ - - Chip::Chip() - { - reg08 = 0; - reg04 = 0; - regBD = 0; - reg104 = 0; - opl3Active = 0; - //Extra zeros! - vibratoIndex = 0; - tremoloIndex = 0; - vibratoSign = 0; - vibratoShift = 0; - tremoloValue = 0; - vibratoStrength = 0; - tremoloStrength = 0; - waveFormMask = 0; - lfoCounter = 0; - lfoAdd = 0; - noiseCounter = 0; - noiseAdd = 0; - noiseValue = 0; - memset(freqMul, 0, sizeof(Bit32u) * 16); - memset(linearRates, 0, sizeof(Bit32u) * 76); - memset(attackRates, 0, sizeof(Bit32u) * 76); - } - - INLINE Bit32u Chip::ForwardNoise() - { - noiseCounter += noiseAdd; - Bitu count = noiseCounter >> LFO_SH; - noiseCounter &= WAVE_MASK; - - for(; count > 0; --count) - { - //Noise calculation from mame - noiseValue ^= (0x800302) & (0 - (noiseValue & 1)); - noiseValue >>= 1; - } - - return noiseValue; - } - - INLINE Bit32u Chip::ForwardLFO(Bit32u samples) - { - //Current vibrato value, runs 4x slower than tremolo - vibratoSign = (VibratoTable[ vibratoIndex >> 2]) >> 7; - vibratoShift = (VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; - tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength; - //Check hom many samples there can be done before the value changes - Bit32u todo = LFO_MAX - lfoCounter; - Bit32u count = (todo + lfoAdd - 1) / lfoAdd; - - if(count > samples) - { - count = samples; - lfoCounter += count * lfoAdd; - } - else - { - lfoCounter += count * lfoAdd; - lfoCounter &= (LFO_MAX - 1); - //Maximum of 7 vibrato value * 4 - vibratoIndex = (vibratoIndex + 1) & 31; - - //Clip tremolo to the the table size - if(tremoloIndex + 1 < TREMOLO_TABLE) - ++tremoloIndex; - else - tremoloIndex = 0; - } - - return count; - } - - - void Chip::WriteBD(Bit8u val) - { - Bit8u change = regBD ^ val; - - if(!change) - return; - - regBD = val; - //TODO could do this with shift and xor? - vibratoStrength = (val & 0x40) ? 0x00 : 0x01; - tremoloStrength = (val & 0x80) ? 0x00 : 0x02; - - if(val & 0x20) - { - //Drum was just enabled, make sure channel 6 has the right synth - if(change & 0x20) - { - if(opl3Active) - chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; - else - chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; - } - - //Bass Drum - if(val & 0x10) - { - chan[6].op[0].KeyOn(0x2); - chan[6].op[1].KeyOn(0x2); - } - else - { - chan[6].op[0].KeyOff(0x2); - chan[6].op[1].KeyOff(0x2); - } - - //Hi-Hat - if(val & 0x1) - chan[7].op[0].KeyOn(0x2); - else - chan[7].op[0].KeyOff(0x2); - - //Snare - if(val & 0x8) - chan[7].op[1].KeyOn(0x2); - else - chan[7].op[1].KeyOff(0x2); - - //Tom-Tom - if(val & 0x4) - chan[8].op[0].KeyOn(0x2); - else - chan[8].op[0].KeyOff(0x2); - - //Top Cymbal - if(val & 0x2) - chan[8].op[1].KeyOn(0x2); - else - chan[8].op[1].KeyOff(0x2); - - //Toggle keyoffs when we turn off the percussion - } - else if(change & 0x20) - { - //Trigger a reset to setup the original synth handler - chan[6].ResetC0(this); - chan[6].op[0].KeyOff(0x2); - chan[6].op[1].KeyOff(0x2); - chan[7].op[0].KeyOff(0x2); - chan[7].op[1].KeyOff(0x2); - chan[8].op[0].KeyOff(0x2); - chan[8].op[1].KeyOff(0x2); - } - } - - -#define REGOP( _FUNC_ ) \ - index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ - if ( OpOffsetTable[ index ] ) { \ - Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \ - regOp->_FUNC_( this, val ); \ - } - -#define REGCHAN( _FUNC_ ) \ - index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ - if ( ChanOffsetTable[ index ] ) { \ - Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \ - regChan->_FUNC_( this, val ); \ - } - - void Chip::WriteReg(Bit32u reg, Bit8u val) - { - Bitu index = 0; - - switch((reg & 0xf0) >> 4) - { - case 0x00 >> 4: - if(reg == 0x01) - waveFormMask = (val & 0x20) ? 0x7 : 0x0; - else if(reg == 0x104) - { - //Only detect changes in lowest 6 bits - if(!((reg104 ^ val) & 0x3f)) - return; - - //Always keep the highest bit enabled, for checking > 0x80 - reg104 = 0x80 | (val & 0x3f); - } - else if(reg == 0x105) - { - //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register - if(!((opl3Active ^ val) & 1)) - return; - - opl3Active = (val & 1) ? 0xff : 0; - - //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers - for(int i = 0; i < 18; i++) - chan[i].ResetC0(this); - } - else if(reg == 0x08) - reg08 = val; - - case 0x10 >> 4: - break; - - case 0x20 >> 4: - case 0x30 >> 4: - REGOP(Write20); - break; - - case 0x40 >> 4: - case 0x50 >> 4: - REGOP(Write40); - break; - - case 0x60 >> 4: - case 0x70 >> 4: - REGOP(Write60); - break; - - case 0x80 >> 4: - case 0x90 >> 4: - REGOP(Write80); - break; - - case 0xa0 >> 4: - REGCHAN(WriteA0); - break; - - case 0xb0 >> 4: - if(reg == 0xbd) - WriteBD(val); - else - REGCHAN(WriteB0); - - break; - - case 0xc0 >> 4: - REGCHAN(WriteC0); - - case 0xd0 >> 4: - break; - - case 0xe0 >> 4: - case 0xf0 >> 4: - REGOP(WriteE0); - break; - } - } - - - Bit32u Chip::WriteAddr(Bit32u port, Bit8u val) - { - switch(port & 3) - { - case 0: - return val; - - case 2: - if(opl3Active || (val == 0x05)) - return 0x100 | val; - else - return val; - } - - return 0; - } - - void Chip::GenerateBlock2(Bitu total, Bit32s *output) - { - while(total > 0) - { - Bit32u samples = ForwardLFO(total); - memset(output, 0, sizeof(Bit32s) * samples); - int count = 0; - - for(Channel *ch = chan; ch < chan + 9;) - { - count++; - ch = (ch->*(ch->synthHandler))(this, samples, output); - } - - total -= samples; - output += samples; - } - } - - void Chip::GenerateBlock3(Bitu total, Bit32s *output) - { - while(total > 0) - { - Bit32u samples = ForwardLFO((Bit32u)total); - memset(output, 0, sizeof(Bit32s) * samples * 2); - int count = 0; - - for(Channel *ch = chan; ch < chan + 18;) - { - count++; - ch = (ch->*(ch->synthHandler))(this, samples, output); - } - - total -= samples; - output += samples * 2; - } - } - - void Chip::GenerateBlock2_Mix(Bitu total, Bit32s *output) - { - while(total > 0) - { - Bit32u samples = ForwardLFO((Bit32u)total); - int count = 0; - for(Channel *ch = chan; ch < chan + 9;) - { - count++; - ch = (ch->*(ch->synthHandler))(this, samples, output); - } - - total -= samples; - output += samples; - } - } - - void Chip::GenerateBlock3_Mix(Bitu total, Bit32s *output) - { - while(total > 0) - { - Bit32u samples = ForwardLFO(total); - int count = 0; - for(Channel *ch = chan; ch < chan + 18;) - { - count++; - ch = (ch->*(ch->synthHandler))(this, samples, output); - } - total -= samples; - output += samples * 2; - } - } - - void Chip::Setup(Bit32u rate) - { - double original = OPLRATE; - // double original = rate; - double scale = original / (double)rate; - //Noise counter is run at the same precision as general waves - noiseAdd = (Bit32u)(0.5 + scale * (1 << LFO_SH)); - noiseCounter = 0; - noiseValue = 1; //Make sure it triggers the noise xor the first time - //The low frequency oscillation counter - //Every time his overflows vibrato and tremoloindex are increased - lfoAdd = (Bit32u)(0.5 + scale * (1 << LFO_SH)); - lfoCounter = 0; - vibratoIndex = 0; - tremoloIndex = 0; - //With higher octave this gets shifted up - //-1 since the freqCreateTable = *2 - #ifdef WAVE_PRECISION - double freqScale = (1 << 7) * scale * (1 << (WAVE_SH - 1 - 10)); - - for(int i = 0; i < 16; i++) - freqMul[i] = (Bit32u)(0.5 + freqScale * FreqCreateTable[ i ]); - - #else - Bit32u freqScale = (Bit32u)(0.5 + scale * (1 << (WAVE_SH - 1 - 10))); - - for(int i = 0; i < 16; i++) - freqMul[i] = freqScale * FreqCreateTable[ i ]; - - #endif - - //-3 since the real envelope takes 8 steps to reach the single value we supply - for(Bit8u i = 0; i < 76; i++) - { - Bit8u index, shift; - EnvelopeSelect(i, index, shift); - linearRates[i] = (Bit32u)(scale * (EnvelopeIncreaseTable[ index ] << (RATE_SH + ENV_EXTRA - shift - 3))); - } - - if(rate == 48000) - { - /* BISQWIT ADD: Use precalculated table for this common sample-rate. - * Because the actual generation code, below, is MOLASSES SLOW on DOS. - */ - static const Bit32u precalculated_table[62] = - { - 2152, 2700, 3228, 3712, 4304, 5399, 6456, 7424, 8608, 10799, 12912, 14849, 17216, 21598, - 25824, 29698, 34432, 43196, 51650, 59398, 68864, 86392, 103310, 118795, 137746, 172847, - 206619, 237693, 275559, 345774, 413238, 475500, 543030, 678787, 814545, 950302, 1086060, - 1357575, 1629090, 1900605, 2172120, 2715151, 3258181, 3801211, 4344241, 5430302, - 6516362, 7602423, 8688483, 10860604, 13032725, 15204846, 17376967, 21721209, 26065451, - 30409693, 34753934, 43442418, 52130902, 60819386, 69507869, 69507869 - }; - - for(Bit8u i = 0; i < 62; i++) - attackRates[i] = precalculated_table[i]; - } - else if(rate == 44100) - { - static const Bit32u precalculated_table[62] = - { - 2342, 2939, 3513, 4040, 4685, 5877, 7027, 8081, 9369, 11754, 14054, 16162, 18738, 23508, - 28108, 32325, 37478, 47018, 56219, 64649, 74965, 94044, 112448, 129292, 149929, 188132, - 224945, 258713, 300002, 376263, 449999, 517550, 591053, 738816, 886579, 1034343, 1182106, - 1477633, 1773159, 2068686, 2364213, 2955266, 3546319, 4137373, 4728426, 5910533, - 7092639, 8274746, 9456853, 11821066, 14185279, 16549492, 18913706, 23642132, 28370559, - 33098985, 37827412, 47284265, 56741118, 66197971, 75654824, 75654824 - }; - - for(Bit8u i = 0; i < 62; i++) - attackRates[i] = precalculated_table[i]; - } - else if(rate == 22050) - { - static const Bit32u precalculated_table[62] = - { - 4685, 5877, 7027, 8081, 9369, 11754, 14054, 16162, 18738, 23508, 28108, 32325, 37478, - 47018, 56219, 64649, 74965, 94044, 112448, 129292, 149929, 188132, 224945, 258713, 300002, - 376263, 449999, 517550, 591053, 738816, 886579, 1034343, 1182106, 1477633, 1773159, - 2068686, 2364213, 2955266, 3546319, 4137373, 4728426, 5910533, 7092639, 8274746, - 9456853, 11821066, 14185279, 16549492, 18913706, 23642132, 28370559, 33098985, - 37827412, 47284265, 56741118, 66197971, 75654824, 94568530, 113482236, 132395942, - 151309648, 151309648 - }; - - for(Bit8u i = 0; i < 62; i++) - attackRates[i] = precalculated_table[i]; - } - //Generate the best matching attack rate - else for(Bit8u i = 0; i < 62; i++) - { - Bit8u index, shift; - EnvelopeSelect(i, index, shift); - //Original amount of samples the attack would take - Bit32s original = (Bit32u)((AttackSamplesTable[ index ] << shift) / scale); - Bit32s guessAdd = (Bit32u)(scale * (EnvelopeIncreaseTable[ index ] << (RATE_SH - shift - 3))); - Bit32s bestAdd = guessAdd; - Bit32u bestDiff = 1 << 30; - - for(Bit32u passes = 0; passes < 16; passes ++) - { - Bit32s volume = ENV_MAX; - Bit32s samples = 0; - Bit32u count = 0; - - while(volume > 0 && samples < original * 2) - { - count += guessAdd; - Bit32s change = count >> RATE_SH; - count &= RATE_MASK; - - if(GCC_UNLIKELY(change)) // less than 1 % - volume += (~volume * change) >> 3; - - samples++; - } - - Bit32s diff = original - samples; - Bit32u lDiff = labs(diff); - - //Init last on first pass - if(lDiff < bestDiff) - { - bestDiff = lDiff; - bestAdd = guessAdd; - - if(!bestDiff) - break; - } - - //Below our target - if(diff < 0) - { - //Better than the last time - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = ((guessAdd * mul) >> 12); - guessAdd++; - } - else if(diff > 0) - { - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = (guessAdd * mul) >> 12; - guessAdd--; - } - } - - attackRates[i] = bestAdd; - } - - /*fprintf(stderr, "attack rate table: "); - for ( Bit8u i = 0; i < 62; i++ ) - fprintf(stderr, ",%u", attackRates[i]); - fprintf(stderr, "\n");*/ - - for(Bit8u i = 62; i < 76; i++) - { - //This should provide instant volume maximizing - attackRates[i] = 8 << RATE_SH; - } - - //Setup the channels with the correct four op flags - //Channels are accessed through a table so they appear linear here - chan[ 0].fourMask = 0x00 | (1 << 0); - chan[ 1].fourMask = 0x80 | (1 << 0); - chan[ 2].fourMask = 0x00 | (1 << 1); - chan[ 3].fourMask = 0x80 | (1 << 1); - chan[ 4].fourMask = 0x00 | (1 << 2); - chan[ 5].fourMask = 0x80 | (1 << 2); - chan[ 9].fourMask = 0x00 | (1 << 3); - chan[10].fourMask = 0x80 | (1 << 3); - chan[11].fourMask = 0x00 | (1 << 4); - chan[12].fourMask = 0x80 | (1 << 4); - chan[13].fourMask = 0x00 | (1 << 5); - chan[14].fourMask = 0x80 | (1 << 5); - //mark the percussion channels - chan[ 6].fourMask = 0x40; - chan[ 7].fourMask = 0x40; - chan[ 8].fourMask = 0x40; - //Clear Everything in opl3 mode - WriteReg(0x105, 0x1); - - for(int i = 0; i < 512; i++) - { - if(i == 0x105) - continue; - - WriteReg(i, 0xff); - WriteReg(i, 0x0); - } - - WriteReg(0x105, 0x0); - - //Clear everything in opl2 mode - for(int i = 0; i < 255; i++) - { - WriteReg(i, 0xff); - WriteReg(i, 0x0); - } - } - - static bool doneTables = false; - void InitTables(void) - { - if(doneTables) - return; - - doneTables = true; - #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) - - //Exponential volume table, same as the real adlib - for(int i = 0; i < 256; i++) - { - //Save them in reverse - ExpTable[i] = (int)(0.5 + (pow(2.0, (255 - i) * (1.0 / 256)) - 1) * 1024); - ExpTable[i] += 1024; //or remove the -1 oh well :) - //Preshift to the left once so the final volume can shift to the right - ExpTable[i] *= 2; - } - - #endif - #if ( DBOPL_WAVE == WAVE_HANDLER ) - - //Add 0.5 for the trunc rounding of the integer cast - //Do a PI sinetable instead of the original 0.5 PI - for(int i = 0; i < 512; i++) - SinTable[i] = (Bit16s)(0.5 - log10(sin((i + 0.5) * (PI / 512.0))) / log10(2.0) * 256); - - #endif - #if ( DBOPL_WAVE == WAVE_TABLEMUL ) - - //Multiplication based tables - for(int i = 0; i < 384; i++) - { - int s = i * 8; - //TODO maybe keep some of the precision errors of the original table? - double val = (0.5 + (pow(2.0, -1.0 + (255 - s) * (1.0 / 256))) * (1 << MUL_SH)); - MulTable[i] = (Bit16u)(val); - } - - //Sine Wave Base - for(int i = 0; i < 512; i++) - { - WaveTable[ 0x0200 + i ] = (Bit16s)(sin((i + 0.5) * (PI / 512.0)) * 4084); - WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; - } - - //Exponential wave - for(int i = 0; i < 256; i++) - { - WaveTable[ 0x700 + i ] = (Bit16s)(0.5 + (pow(2.0, -1.0 + (255 - i * 8) * (1.0 / 256))) * 4085); - WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; - } - - #endif - #if ( DBOPL_WAVE == WAVE_TABLELOG ) - - //Sine Wave Base - for(int i = 0; i < 512; i++) - { - WaveTable[ 0x0200 + i ] = (Bit16s)(0.5 - log10(sin((i + 0.5) * (PI / 512.0))) / log10(2.0) * 256); - WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; - } - - //Exponential wave - for(int i = 0; i < 256; i++) - { - WaveTable[ 0x700 + i ] = i * 8; - WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; - } - - #endif - // | |//\\|____|WAV7|//__|/\ |____|/\/\| - // |\\//| | |WAV7| | \/| | | - // |06 |0126|27 |7 |3 |4 |4 5 |5 | - #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) - - for(int i = 0; i < 256; i++) - { - //Fill silence gaps - WaveTable[ 0x400 + i ] = WaveTable[0]; - WaveTable[ 0x500 + i ] = WaveTable[0]; - WaveTable[ 0x900 + i ] = WaveTable[0]; - WaveTable[ 0xc00 + i ] = WaveTable[0]; - WaveTable[ 0xd00 + i ] = WaveTable[0]; - //Replicate sines in other pieces - WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; - //double speed sines - WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; - WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; - WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; - WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; - } - - #endif - - //Create the ksl table - for(int oct = 0; oct < 8; oct++) - { - int base = oct * 8; - - for(int i = 0; i < 16; i++) - { - int val = base - KslCreateTable[i]; - - if(val < 0) - val = 0; - - //*4 for the final range to match attenuation range - KslTable[ oct * 16 + i ] = val * 4; - } - } - - //Create the Tremolo table, just increase and decrease a triangle wave - for(Bit8u i = 0; i < TREMOLO_TABLE / 2; i++) - { - Bit8u val = i << ENV_EXTRA; - TremoloTable[i] = val; - TremoloTable[TREMOLO_TABLE - 1 - i] = val; - } - - //Create a table with offsets of the channels from the start of the chip - DBOPL::Chip *chip = 0; - - for(Bitu i = 0; i < 32; i++) - { - Bitu index = i & 0xf; - - if(index >= 9) - { - ChanOffsetTable[i] = 0; - continue; - } - - //Make sure the four op channels follow eachother - if(index < 6) - index = (index % 3) * 2 + (index / 3); - - //Add back the bits for highest ones - if(i >= 16) - index += 9; - - intptr_t blah = reinterpret_cast<intptr_t>(&(chip->chan[ index ])); - ChanOffsetTable[i] = static_cast<Bit16u>(blah); - } - - //Same for operators - for(Bitu i = 0; i < 64; i++) - { - if(i % 8 >= 6 || ((i / 8) % 4 == 3)) - { - OpOffsetTable[i] = 0; - continue; - } - - Bitu chNum = (i / 8) * 3 + (i % 8) % 3; - - //Make sure we use 16 and up for the 2nd range to match the chanoffset gap - if(chNum >= 12) - chNum += 16 - 12; - - Bitu opNum = (i % 8) / 3; - DBOPL::Channel *chan = NULL; - intptr_t blah = reinterpret_cast<intptr_t>(&(chan->op[opNum])); - OpOffsetTable[i] = static_cast<Bit16u>((intptr_t)ChanOffsetTable[ chNum ] + blah); - } - - #if 0 - - //Stupid checks if table's are correct - for(Bitu i = 0; i < 18; i++) - { - Bit32u find = (Bit16u)(&(chip->chan[ i ])); - - for(Bitu c = 0; c < 32; c++) - { - if(ChanOffsetTable[c] == find) - { - find = 0; - break; - } - } - - if(find) - find = find; - } - - for(Bitu i = 0; i < 36; i++) - { - Bit32u find = (Bit16u)(&(chip->chan[ i / 2 ].op[i % 2])); - - for(Bitu c = 0; c < 64; c++) - { - if(OpOffsetTable[c] == find) - { - find = 0; - break; - } - } - - if(find) - find = find; - } - - #endif - } - - Bit32u Handler::WriteAddr(Bit32u port, Bit8u val) - { - return chip.WriteAddr(port, val); - } - void Handler::WriteReg(Bit32u addr, Bit8u val) - { - chip.WriteReg(addr, val); - } - - void Handler::Generate(void(*AddSamples_m32)(Bitu, Bit32s *), - void(*AddSamples_s32)(Bitu, Bit32s *), - Bitu samples) - { - Bit32s buffer[ 512 * 2 ]; - - if(GCC_UNLIKELY(samples > 512)) - samples = 512; - - if(!chip.opl3Active) - { - chip.GenerateBlock2(samples, buffer); - AddSamples_m32(samples, buffer); - } - else - { - chip.GenerateBlock3(samples, buffer); - AddSamples_s32(samples, buffer); - } - } - - void Handler::GenerateArr(Bit32s *out, Bitu *samples) - { - if(GCC_UNLIKELY(*samples > 512)) - *samples = 512; - - if(!chip.opl3Active) - chip.GenerateBlock2(*samples, out); - else - chip.GenerateBlock3(*samples, out); - } - - void Handler::GenerateArr(Bit32s *out, ssize_t *samples) - { - if(GCC_UNLIKELY(*samples > 512)) - *samples = 512; - - if(!chip.opl3Active) - chip.GenerateBlock2(static_cast<Bitu>(*samples), out); - else - chip.GenerateBlock3(static_cast<Bitu>(*samples), out); - } - - void Handler::GenerateArr(Bit16s *out, ssize_t *samples) - { - Bit32s out32[1024]; - if(GCC_UNLIKELY(*samples > 512)) - *samples = 512; - memset(out32, 0, sizeof(Bit32s) * 1024); - if(!chip.opl3Active) - chip.GenerateBlock2(static_cast<Bitu>(*samples), out32); - else - chip.GenerateBlock3(static_cast<Bitu>(*samples), out32); - ssize_t sz = *samples * 2; - for(ssize_t i = 0; i < sz; i++) - out[i] = static_cast<Bit16s>(DBOPL_CLAMP(out32[i], static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX))); - } - - void Handler::GenerateArrMix(Bit32s *out, ssize_t *samples) - { - if(GCC_UNLIKELY(*samples > 512)) - *samples = 512; - if(!chip.opl3Active) - chip.GenerateBlock2_Mix(static_cast<Bitu>(*samples), out); - else - chip.GenerateBlock3_Mix(static_cast<Bitu>(*samples), out); - } - - void Handler::GenerateArrMix(Bit16s *out, ssize_t *samples) - { - Bit32s out32[1024]; - if(GCC_UNLIKELY(*samples > 512)) - *samples = 512; - memset(out32, 0, sizeof(Bit32s) * 1024); - if(!chip.opl3Active) - chip.GenerateBlock2(static_cast<Bitu>(*samples), out32); - else - chip.GenerateBlock3(static_cast<Bitu>(*samples), out32); - ssize_t sz = *samples * 2; - for(ssize_t i = 0; i < sz; i++) - out[i] += static_cast<Bit16s>(DBOPL_CLAMP(out32[i], static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX))); - } - - - void Handler::Init(Bitu rate) - { - InitTables(); - chip.Setup((Bit32u)rate); - } - - -} //Namespace DBOPL - -//#endif //ADLMIDI_USE_DOSBOX_OPL +#endif +} + +Bits INLINE Operator::GetSample( Bits modulation ) { + Bitu vol = ForwardVolume(); + if ( ENV_SILENT( vol ) ) { + //Simply forward the wave + waveIndex += waveCurrent; + return 0; + } else { + Bitu index = ForwardWave(); + index += modulation; + return GetWave( index, vol ); + } +} + +Operator::Operator() { + chanData = 0; + freqMul = 0; + waveIndex = 0; + waveAdd = 0; + waveCurrent = 0; + keyOn = 0; + ksr = 0; + reg20 = 0; + reg40 = 0; + reg60 = 0; + reg80 = 0; + regE0 = 0; + SetState( OFF ); + rateZero = (1 << OFF); + sustainLevel = ENV_MAX; + currentLevel = ENV_MAX; + totalLevel = ENV_MAX; + volume = ENV_MAX; + releaseAdd = 0; +} + +/* + Channel +*/ + +Channel::Channel() { + old[0] = old[1] = 0; + chanData = 0; + regB0 = 0; + regC0 = 0; + maskLeft = -1; + maskRight = -1; + feedback = 31; + fourMask = 0; + synthHandler = &Channel::BlockTemplate< sm2FM >; +} + +void Channel::SetChanData( const Chip* chip, Bit32u data ) { + Bit32u change = chanData ^ data; + chanData = data; + Op( 0 )->chanData = data; + Op( 1 )->chanData = data; + //Since a frequency update triggered this, always update frequency + Op( 0 )->UpdateFrequency(); + Op( 1 )->UpdateFrequency(); + if ( change & ( 0xff << SHIFT_KSLBASE ) ) { + Op( 0 )->UpdateAttenuation(); + Op( 1 )->UpdateAttenuation(); + } + if ( change & ( 0xff << SHIFT_KEYCODE ) ) { + Op( 0 )->UpdateRates( chip ); + Op( 1 )->UpdateRates( chip ); + } +} + +void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) { + //Extrace the frequency bits + Bit32u data = chanData & 0xffff; + Bit32u kslBase = KslTable[ data >> 6 ]; + Bit32u keyCode = ( data & 0x1c00) >> 9; + if ( chip->reg08 & 0x40 ) { + keyCode |= ( data & 0x100)>>8; /* notesel == 1 */ + } else { + keyCode |= ( data & 0x200)>>9; /* notesel == 0 */ + } + //Add the keycode and ksl into the highest bits of chanData + data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE ); + ( this + 0 )->SetChanData( chip, data ); + if ( fourOp & 0x3f ) { + ( this + 1 )->SetChanData( chip, data ); + } +} + +void Channel::WriteA0( const Chip* chip, Bit8u val ) { + Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; + //Don't handle writes to silent fourop channels + if ( fourOp > 0x80 ) + return; + Bit32u change = (chanData ^ val ) & 0xff; + if ( change ) { + chanData ^= change; + UpdateFrequency( chip, fourOp ); + } +} + +void Channel::WriteB0( const Chip* chip, Bit8u val ) { + Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; + //Don't handle writes to silent fourop channels + if ( fourOp > 0x80 ) + return; + Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00; + if ( change ) { + chanData ^= change; + UpdateFrequency( chip, fourOp ); + } + //Check for a change in the keyon/off state + if ( !(( val ^ regB0) & 0x20)) + return; + regB0 = val; + if ( val & 0x20 ) { + Op(0)->KeyOn( 0x1 ); + Op(1)->KeyOn( 0x1 ); + if ( fourOp & 0x3f ) { + ( this + 1 )->Op(0)->KeyOn( 1 ); + ( this + 1 )->Op(1)->KeyOn( 1 ); + } + } else { + Op(0)->KeyOff( 0x1 ); + Op(1)->KeyOff( 0x1 ); + if ( fourOp & 0x3f ) { + ( this + 1 )->Op(0)->KeyOff( 1 ); + ( this + 1 )->Op(1)->KeyOff( 1 ); + } + } +} + +void Channel::WriteC0(const Chip* chip, Bit8u val) { + Bit8u change = val ^ regC0; + if (!change) + return; + regC0 = val; + feedback = (regC0 >> 1) & 7; + if (feedback) { + //We shift the input to the right 10 bit wave index value + feedback = 9 - feedback; + } + else { + feedback = 31; + } + UpdateSynth(chip); +} + +void Channel::UpdateSynth( const Chip* chip ) { + //Select the new synth mode + if ( chip->opl3Active ) { + //4-op mode enabled for this channel + if ( (chip->reg104 & fourMask) & 0x3f ) { + Channel* chan0, *chan1; + //Check if it's the 2nd channel in a 4-op + if ( !(fourMask & 0x80 ) ) { + chan0 = this; + chan1 = this + 1; + } else { + chan0 = this - 1; + chan1 = this; + } + + Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 ); + switch ( synth ) { + case 0: + chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >; + break; + case 1: + chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >; + break; + case 2: + chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >; + break; + case 3: + chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; + break; + } + //Disable updating percussion channels + } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { + + //Regular dual op, am or fm + } else if (regC0 & 1 ) { + synthHandler = &Channel::BlockTemplate< sm3AM >; + } else { + synthHandler = &Channel::BlockTemplate< sm3FM >; + } + maskLeft = (regC0 & 0x10 ) ? -1 : 0; + maskRight = (regC0 & 0x20 ) ? -1 : 0; + //opl2 active + } else { + //Disable updating percussion channels + if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { + + //Regular dual op, am or fm + } else if (regC0 & 1 ) { + synthHandler = &Channel::BlockTemplate< sm2AM >; + } else { + synthHandler = &Channel::BlockTemplate< sm2FM >; + } + } +} + +template< bool opl3Mode> +INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { + Channel* chan = this; + + //BassDrum + Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; + old[0] = old[1]; + old[1] = static_cast<Bit32u>(Op(0)->GetSample( mod )); + + //When bassdrum is in AM mode first operator is ignoed + if ( chan->regC0 & 1 ) { + mod = 0; + } else { + mod = old[0]; + } + Bit32s sample = static_cast<Bit32u>(Op(1)->GetSample( mod )); + + + //Precalculate stuff used by other outputs + Bit32u noiseBit = chip->ForwardNoise() & 0x1; + Bit32u c2 = static_cast<Bit32u>(Op(2)->ForwardWave()); + Bit32u c5 = static_cast<Bit32u>(Op(5)->ForwardWave()); + Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00; + + //Hi-Hat + Bit32u hhVol = static_cast<Bit32u>(Op(2)->ForwardVolume()); + if ( !ENV_SILENT( hhVol ) ) { + Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 ))); + sample += static_cast<Bit32u>(Op(2)->GetWave( hhIndex, hhVol )); + } + //Snare Drum + Bit32u sdVol = static_cast<Bit32u>(Op(3)->ForwardVolume()); + if ( !ENV_SILENT( sdVol ) ) { + Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 ); + sample += static_cast<Bit32u>(Op(3)->GetWave( sdIndex, sdVol )); + } + //Tom-tom + sample += static_cast<Bit32u>(Op(4)->GetSample( 0 )); + + //Top-Cymbal + Bit32u tcVol = static_cast<Bit32u>(Op(5)->ForwardVolume()); + if ( !ENV_SILENT( tcVol ) ) { + Bit32u tcIndex = (1 + phaseBit) << 8; + sample += static_cast<Bit32u>(Op(5)->GetWave( tcIndex, tcVol )); + } + sample <<= 1; + if ( opl3Mode ) { + output[0] += sample; + output[1] += sample; + } else { + output[0] += sample; + } +} + +template<SynthMode mode> +Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { + switch( mode ) { + case sm2AM: + case sm3AM: + if ( Op(0)->Silent() && Op(1)->Silent() ) { + old[0] = old[1] = 0; + return (this + 1); + } + break; + case sm2FM: + case sm3FM: + if ( Op(1)->Silent() ) { + old[0] = old[1] = 0; + return (this + 1); + } + break; + case sm3FMFM: + if ( Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + case sm3AMFM: + if ( Op(0)->Silent() && Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + case sm3FMAM: + if ( Op(1)->Silent() && Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + case sm3AMAM: + if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) { + old[0] = old[1] = 0; + return (this + 2); + } + break; + default: + break; + } + //Init the operators with the the current vibrato and tremolo values + Op( 0 )->Prepare( chip ); + Op( 1 )->Prepare( chip ); + if ( mode > sm4Start ) { + Op( 2 )->Prepare( chip ); + Op( 3 )->Prepare( chip ); + } + if ( mode > sm6Start ) { + Op( 4 )->Prepare( chip ); + Op( 5 )->Prepare( chip ); + } + for ( Bitu i = 0; i < samples; i++ ) { + //Early out for percussion handlers + if ( mode == sm2Percussion ) { + GeneratePercussion<false>( chip, output + i ); + continue; //Prevent some unitialized value bitching + } else if ( mode == sm3Percussion ) { + GeneratePercussion<true>( chip, output + i * 2 ); + continue; //Prevent some unitialized value bitching + } + + //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise + Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; + old[0] = old[1]; + old[1] = static_cast<Bit32u>(Op(0)->GetSample( mod )); + Bit32s sample; + Bit32s out0 = old[0]; + if ( mode == sm2AM || mode == sm3AM ) { + sample = static_cast<Bit32u>(out0 + Op(1)->GetSample( 0 )); + } else if ( mode == sm2FM || mode == sm3FM ) { + sample = static_cast<Bit32u>(Op(1)->GetSample( out0 )); + } else if ( mode == sm3FMFM ) { + Bits next = Op(1)->GetSample( out0 ); + next = Op(2)->GetSample( next ); + sample = static_cast<Bit32u>(Op(3)->GetSample( next )); + } else if ( mode == sm3AMFM ) { + sample = out0; + Bits next = Op(1)->GetSample( 0 ); + next = Op(2)->GetSample( next ); + sample += static_cast<Bit32u>(Op(3)->GetSample( next )); + } else if ( mode == sm3FMAM ) { + sample = static_cast<Bit32u>(Op(1)->GetSample( out0 )); + Bits next = Op(2)->GetSample( 0 ); + sample += static_cast<Bit32u>(Op(3)->GetSample( next )); + } else if ( mode == sm3AMAM ) { + sample = out0; + Bits next = Op(1)->GetSample( 0 ); + sample += static_cast<Bit32u>(Op(2)->GetSample( next )); + sample += static_cast<Bit32u>(Op(3)->GetSample( 0 )); + } + switch( mode ) { + case sm2AM: + case sm2FM: + output[ i ] += sample; + break; + case sm3AM: + case sm3FM: + case sm3FMFM: + case sm3AMFM: + case sm3FMAM: + case sm3AMAM: + output[ i * 2 + 0 ] += sample & maskLeft; + output[ i * 2 + 1 ] += sample & maskRight; + break; + default: + break; + } + } + switch( mode ) { + case sm2AM: + case sm2FM: + case sm3AM: + case sm3FM: + return ( this + 1 ); + case sm3FMFM: + case sm3AMFM: + case sm3FMAM: + case sm3AMAM: + return( this + 2 ); + case sm2Percussion: + case sm3Percussion: + return( this + 3 ); + } + return 0; +} + +/* + Chip +*/ + +Chip::Chip() { + reg08 = 0; + reg04 = 0; + regBD = 0; + reg104 = 0; + opl3Active = 0; +} + +INLINE Bit32u Chip::ForwardNoise() { + noiseCounter += noiseAdd; + Bitu count = noiseCounter >> LFO_SH; + noiseCounter &= WAVE_MASK; + for ( ; count > 0; --count ) { + //Noise calculation from mame + noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) ); + noiseValue >>= 1; + } + return noiseValue; +} + +INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) { + //Current vibrato value, runs 4x slower than tremolo + vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7; + vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; + tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength; + + //Check hom many samples there can be done before the value changes + Bit32u todo = LFO_MAX - lfoCounter; + Bit32u count = (todo + lfoAdd - 1) / lfoAdd; + if ( count > samples ) { + count = samples; + lfoCounter += count * lfoAdd; + } else { + lfoCounter += count * lfoAdd; + lfoCounter &= (LFO_MAX - 1); + //Maximum of 7 vibrato value * 4 + vibratoIndex = ( vibratoIndex + 1 ) & 31; + //Clip tremolo to the the table size + if ( tremoloIndex + 1 < TREMOLO_TABLE ) + ++tremoloIndex; + else + tremoloIndex = 0; + } + return count; +} + + +void Chip::WriteBD( Bit8u val ) { + Bit8u change = regBD ^ val; + if ( !change ) + return; + regBD = val; + //TODO could do this with shift and xor? + vibratoStrength = (val & 0x40) ? 0x00 : 0x01; + tremoloStrength = (val & 0x80) ? 0x00 : 0x02; + if ( val & 0x20 ) { + //Drum was just enabled, make sure channel 6 has the right synth + if ( change & 0x20 ) { + if ( opl3Active ) { + chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; + } else { + chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; + } + } + //Bass Drum + if ( val & 0x10 ) { + chan[6].op[0].KeyOn( 0x2 ); + chan[6].op[1].KeyOn( 0x2 ); + } else { + chan[6].op[0].KeyOff( 0x2 ); + chan[6].op[1].KeyOff( 0x2 ); + } + //Hi-Hat + if ( val & 0x1 ) { + chan[7].op[0].KeyOn( 0x2 ); + } else { + chan[7].op[0].KeyOff( 0x2 ); + } + //Snare + if ( val & 0x8 ) { + chan[7].op[1].KeyOn( 0x2 ); + } else { + chan[7].op[1].KeyOff( 0x2 ); + } + //Tom-Tom + if ( val & 0x4 ) { + chan[8].op[0].KeyOn( 0x2 ); + } else { + chan[8].op[0].KeyOff( 0x2 ); + } + //Top Cymbal + if ( val & 0x2 ) { + chan[8].op[1].KeyOn( 0x2 ); + } else { + chan[8].op[1].KeyOff( 0x2 ); + } + //Toggle keyoffs when we turn off the percussion + } else if ( change & 0x20 ) { + //Trigger a reset to setup the original synth handler + //This makes it call + chan[6].UpdateSynth( this ); + chan[6].op[0].KeyOff( 0x2 ); + chan[6].op[1].KeyOff( 0x2 ); + chan[7].op[0].KeyOff( 0x2 ); + chan[7].op[1].KeyOff( 0x2 ); + chan[8].op[0].KeyOff( 0x2 ); + chan[8].op[1].KeyOff( 0x2 ); + } +} + + +#define REGOP( _FUNC_ ) \ + index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ + if ( OpOffsetTable[ index ] ) { \ + Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \ + regOp->_FUNC_( this, val ); \ + } + +#define REGCHAN( _FUNC_ ) \ + index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ + if ( ChanOffsetTable[ index ] ) { \ + Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \ + regChan->_FUNC_( this, val ); \ + } + +//Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers +void Chip::UpdateSynths() { + for (int i = 0; i < 18; i++) { + chan[i].UpdateSynth(this); + } +} + + +void Chip::WriteReg( Bit32u reg, Bit8u val ) { + Bitu index; + switch ( (reg & 0xf0) >> 4 ) { + case 0x00 >> 4: + if ( reg == 0x01 ) { + waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; + } else if ( reg == 0x104 ) { + //Only detect changes in lowest 6 bits + if ( !((reg104 ^ val) & 0x3f) ) + return; + //Always keep the highest bit enabled, for checking > 0x80 + reg104 = 0x80 | ( val & 0x3f ); + //Switch synths when changing the 4op combinations + UpdateSynths(); + } else if ( reg == 0x105 ) { + //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register + if ( !((opl3Active ^ val) & 1 ) ) + return; + opl3Active = ( val & 1 ) ? 0xff : 0; + //Just tupdate the synths now that opl3 most have been enabled + //This isn't how the real card handles it but need to switch to stereo generating handlers + UpdateSynths(); + } else if ( reg == 0x08 ) { + reg08 = val; + } + case 0x10 >> 4: + break; + case 0x20 >> 4: + case 0x30 >> 4: + REGOP( Write20 ); + break; + case 0x40 >> 4: + case 0x50 >> 4: + REGOP( Write40 ); + break; + case 0x60 >> 4: + case 0x70 >> 4: + REGOP( Write60 ); + break; + case 0x80 >> 4: + case 0x90 >> 4: + REGOP( Write80 ); + break; + case 0xa0 >> 4: + REGCHAN( WriteA0 ); + break; + case 0xb0 >> 4: + if ( reg == 0xbd ) { + WriteBD( val ); + } else { + REGCHAN( WriteB0 ); + } + break; + case 0xc0 >> 4: + REGCHAN( WriteC0 ); + case 0xd0 >> 4: + break; + case 0xe0 >> 4: + case 0xf0 >> 4: + REGOP( WriteE0 ); + break; + } +} + + +Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { + switch ( port & 3 ) { + case 0: + return val; + case 2: + if ( opl3Active || (val == 0x05) ) + return 0x100 | val; + else + return val; + } + return 0; +} + +void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); + memset(output, 0, sizeof(Bit32s) * samples); +// int count = 0; + for( Channel* ch = chan; ch < chan + 9; ) { +// count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples; + } +} + +void Chip::GenerateBlock2_Mix( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); +// int count = 0; + for( Channel* ch = chan; ch < chan + 9; ) { +// count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples; + } +} + +void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); + memset(output, 0, sizeof(Bit32s) * samples *2); +// int count = 0; + for( Channel* ch = chan; ch < chan + 18; ) { +// count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples * 2; + } +} + +void Chip::GenerateBlock3_Mix( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); +// int count = 0; + for( Channel* ch = chan; ch < chan + 18; ) { +// count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples * 2; + } +} + +void Chip::Setup( Bit32u rate ) { + double original = OPLRATE; +// double original = rate; + double scale = original / (double)rate; + + //Noise counter is run at the same precision as general waves + noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); + noiseCounter = 0; + noiseValue = 1; //Make sure it triggers the noise xor the first time + //The low frequency oscillation counter + //Every time his overflows vibrato and tremoloindex are increased + lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); + lfoCounter = 0; + vibratoIndex = 0; + tremoloIndex = 0; + + //With higher octave this gets shifted up + //-1 since the freqCreateTable = *2 +#ifdef WAVE_PRECISION + double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10)); + for ( int i = 0; i < 16; i++ ) { + freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] ); + } +#else + Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10))); + for ( int i = 0; i < 16; i++ ) { + freqMul[i] = freqScale * FreqCreateTable[ i ]; + } +#endif + + //-3 since the real envelope takes 8 steps to reach the single value we supply + for ( Bit8u i = 0; i < 76; i++ ) { + Bit8u index, shift; + EnvelopeSelect( i, index, shift ); + linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); + } +// Bit32s attackDiffs[62]; + //Generate the best matching attack rate + for ( Bit8u i = 0; i < 62; i++ ) { + Bit8u index, shift; + EnvelopeSelect( i, index, shift ); + //Original amount of samples the attack would take + Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale); + + Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))); + Bit32s bestAdd = guessAdd; + Bit32u bestDiff = 1 << 30; + for( Bit32u passes = 0; passes < 16; passes ++ ) { + Bit32s volume = ENV_MAX; + Bit32s samples = 0; + Bit32u count = 0; + while ( volume > 0 && samples < original * 2 ) { + count += guessAdd; + Bit32s change = count >> RATE_SH; + count &= RATE_MASK; + if ( GCC_UNLIKELY(change) ) { // less than 1 % + volume += ( ~volume * change ) >> 3; + } + samples++; + + } + Bit32s diff = original - samples; + Bit32u lDiff = labs( diff ); + //Init last on first pass + if ( lDiff < bestDiff ) { + bestDiff = lDiff; + bestAdd = guessAdd; + //We hit an exactly matching sample count + if ( !bestDiff ) + break; + } + //Linear correction factor, not exactly perfect but seems to work + double correct = (original - diff) / (double)original; + guessAdd = (Bit32u)(guessAdd * correct); + //Below our target + if ( diff < 0 ) { + //Always add one here for rounding, an overshoot will get corrected by another pass decreasing + guessAdd++; + } + } + attackRates[i] = bestAdd; + //Keep track of the diffs for some debugging +// attackDiffs[i] = bestDiff; + } + for ( Bit8u i = 62; i < 76; i++ ) { + //This should provide instant volume maximizing + attackRates[i] = 8 << RATE_SH; + } + //Setup the channels with the correct four op flags + //Channels are accessed through a table so they appear linear here + chan[ 0].fourMask = 0x00 | ( 1 << 0 ); + chan[ 1].fourMask = 0x80 | ( 1 << 0 ); + chan[ 2].fourMask = 0x00 | ( 1 << 1 ); + chan[ 3].fourMask = 0x80 | ( 1 << 1 ); + chan[ 4].fourMask = 0x00 | ( 1 << 2 ); + chan[ 5].fourMask = 0x80 | ( 1 << 2 ); + + chan[ 9].fourMask = 0x00 | ( 1 << 3 ); + chan[10].fourMask = 0x80 | ( 1 << 3 ); + chan[11].fourMask = 0x00 | ( 1 << 4 ); + chan[12].fourMask = 0x80 | ( 1 << 4 ); + chan[13].fourMask = 0x00 | ( 1 << 5 ); + chan[14].fourMask = 0x80 | ( 1 << 5 ); + + //mark the percussion channels + chan[ 6].fourMask = 0x40; + chan[ 7].fourMask = 0x40; + chan[ 8].fourMask = 0x40; + + //Clear Everything in opl3 mode + WriteReg( 0x105, 0x1 ); + for ( int i = 0; i < 512; i++ ) { + if ( i == 0x105 ) + continue; + WriteReg( i, 0xff ); + WriteReg( i, 0x0 ); + } + WriteReg( 0x105, 0x0 ); + //Clear everything in opl2 mode + for ( int i = 0; i < 255; i++ ) { + WriteReg( i, 0xff ); + WriteReg( i, 0x0 ); + } +} + +static bool doneTables = false; +void InitTables( void ) { + if ( doneTables ) + return; + doneTables = true; +#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) + //Exponential volume table, same as the real adlib + for ( int i = 0; i < 256; i++ ) { + //Save them in reverse + ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); + ExpTable[i] += 1024; //or remove the -1 oh well :) + //Preshift to the left once so the final volume can shift to the right + ExpTable[i] *= 2; + } +#endif +#if ( DBOPL_WAVE == WAVE_HANDLER ) + //Add 0.5 for the trunc rounding of the integer cast + //Do a PI sinetable instead of the original 0.5 PI + for ( int i = 0; i < 512; i++ ) { + SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); + } +#endif +#if ( DBOPL_WAVE == WAVE_TABLEMUL ) + //Multiplication based tables + for ( int i = 0; i < 384; i++ ) { + int s = i * 8; + //TODO maybe keep some of the precision errors of the original table? + double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); + MulTable[i] = (Bit16u)(val); + } + + //Sine Wave Base + for ( int i = 0; i < 512; i++ ) { + WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); + WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; + } + //Exponential wave + for ( int i = 0; i < 256; i++ ) { + WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); + WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; + } +#endif +#if ( DBOPL_WAVE == WAVE_TABLELOG ) + //Sine Wave Base + for ( int i = 0; i < 512; i++ ) { + WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); + WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; + } + //Exponential wave + for ( int i = 0; i < 256; i++ ) { + WaveTable[ 0x700 + i ] = i * 8; + WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; + } +#endif + + // | |//\\|____|WAV7|//__|/\ |____|/\/\| + // |\\//| | |WAV7| | \/| | | + // |06 |0126|27 |7 |3 |4 |4 5 |5 | + +#if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) + for ( int i = 0; i < 256; i++ ) { + //Fill silence gaps + WaveTable[ 0x400 + i ] = WaveTable[0]; + WaveTable[ 0x500 + i ] = WaveTable[0]; + WaveTable[ 0x900 + i ] = WaveTable[0]; + WaveTable[ 0xc00 + i ] = WaveTable[0]; + WaveTable[ 0xd00 + i ] = WaveTable[0]; + //Replicate sines in other pieces + WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; + //double speed sines + WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; + WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; + WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; + WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; + } +#endif + + //Create the ksl table + for ( int oct = 0; oct < 8; oct++ ) { + int base = oct * 8; + for ( int i = 0; i < 16; i++ ) { + int val = base - KslCreateTable[i]; + if ( val < 0 ) + val = 0; + //*4 for the final range to match attenuation range + KslTable[ oct * 16 + i ] = val * 4; + } + } + //Create the Tremolo table, just increase and decrease a triangle wave + for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) { + Bit8u val = i << ENV_EXTRA; + TremoloTable[i] = val; + TremoloTable[TREMOLO_TABLE - 1 - i] = val; + } + //Create a table with offsets of the channels from the start of the chip + DBOPL::Chip* chip = 0; + for ( Bitu i = 0; i < 32; i++ ) { + Bitu index = i & 0xf; + if ( index >= 9 ) { + ChanOffsetTable[i] = 0; + continue; + } + //Make sure the four op channels follow eachother + if ( index < 6 ) { + index = (index % 3) * 2 + ( index / 3 ); + } + //Add back the bits for highest ones + if ( i >= 16 ) + index += 9; + Bitu blah = reinterpret_cast<Bitu>( &(chip->chan[ index ]) ); + ChanOffsetTable[i] = static_cast<Bit16u>(blah); + } + //Same for operators + for ( Bitu i = 0; i < 64; i++ ) { + if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) { + OpOffsetTable[i] = 0; + continue; + } + Bitu chNum = (i / 8) * 3 + (i % 8) % 3; + //Make sure we use 16 and up for the 2nd range to match the chanoffset gap + if ( chNum >= 12 ) + chNum += 16 - 12; + Bitu opNum = ( i % 8 ) / 3; + DBOPL::Channel* chan = 0; + Bitu blah = reinterpret_cast<Bitu>( &(chan->op[opNum]) ); + OpOffsetTable[i] = static_cast<Bit16u>(ChanOffsetTable[ chNum ] + blah); + } +#if 0 + //Stupid checks if table's are correct + for ( Bitu i = 0; i < 18; i++ ) { + Bit32u find = (Bit16u)( &(chip->chan[ i ]) ); + for ( Bitu c = 0; c < 32; c++ ) { + if ( ChanOffsetTable[c] == find ) { + find = 0; + break; + } + } + if ( find ) { + find = find; + } + } + for ( Bitu i = 0; i < 36; i++ ) { + Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) ); + for ( Bitu c = 0; c < 64; c++ ) { + if ( OpOffsetTable[c] == find ) { + find = 0; + break; + } + } + if ( find ) { + find = find; + } + } +#endif +} + +Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) { + return chip.WriteAddr( port, val ); + +} +void Handler::WriteReg( Bit32u addr, Bit8u val ) { + chip.WriteReg( addr, val ); +} + +#define DB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define DB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define DBOPL_CLAMP(V, MIN, MAX) DB_MAX(DB_MIN(V, (MAX)), (MIN)) + +void Handler::GenerateArr(Bit32s *out, Bitu *samples) +{ + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + if(!chip.opl3Active) + chip.GenerateBlock2(*samples, out); + else + chip.GenerateBlock3(*samples, out); +} + +void Handler::GenerateArr(Bit16s *out, Bitu *samples) +{ + Bit32s out32[1024]; + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + memset(out32, 0, sizeof(Bit32s) * 1024); + if(!chip.opl3Active) + chip.GenerateBlock2(*samples, out32); + else + chip.GenerateBlock3(*samples, out32); + Bitu sz = *samples * 2; + for(Bitu i = 0; i < sz; i++) + out[i] = static_cast<Bit16s>(DBOPL_CLAMP(out32[i], INT16_MIN, INT16_MAX)); +} + +void Handler::GenerateArrMix(Bit32s *out, Bitu *samples) +{ + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + if(!chip.opl3Active) + chip.GenerateBlock2_Mix(*samples, out); + else + chip.GenerateBlock3_Mix(*samples, out); +} + +void Handler::GenerateArrMix(Bit16s *out, Bitu *samples) +{ + Bit32s out32[1024]; + if(GCC_UNLIKELY(*samples > 512)) + *samples = 512; + memset(out32, 0, sizeof(Bit32s) * 1024); + if(!chip.opl3Active) + chip.GenerateBlock2(*samples, out32); + else + chip.GenerateBlock3(*samples, out32); + Bitu sz = *samples * 2; + for(Bitu i = 0; i < sz; i++) + out[i] += static_cast<Bit16s>(DBOPL_CLAMP(out32[i], INT16_MIN, INT16_MAX)); +} + +void Handler::Init( Bitu rate ) { + InitTables(); + chip.Setup( static_cast<Bit32u>(rate) ); +} + + +} //Namespace DBOPL diff --git a/src/chips/dosbox/dbopl.h b/src/chips/dosbox/dbopl.h index 13c606f..73c0aa9 100644 --- a/src/chips/dosbox/dbopl.h +++ b/src/chips/dosbox/dbopl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 The DOSBox Team + * Copyright (C) 2002-2018 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,28 +16,28 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* BEGIN MIDIPLAY GLUE */ +#include <inttypes.h> #include <stdint.h> -#include <stdlib.h> #include <sys/types.h> -typedef unsigned long Bitu; -typedef signed long Bits; -typedef unsigned Bit32u; -typedef int Bit32s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned char Bit8u; -typedef signed char Bit8s; -#define INLINE inline -#ifdef _MSC_VER -#define GCC_UNLIKELY(x) (!!(x) == 0) -#define GCC_LIKELY(x) (!!(x) == 1) + +#if defined(__GNUC__) && defined(__i386__) +#define DB_FASTCALL __attribute__((fastcall)) +#elif defined(_MSC_VER) +#define DB_FASTCALL __fastcall #else -#define GCC_UNLIKELY(x) __builtin_expect((x),0) -#define GCC_LIKELY(x) __builtin_expect((x),1) +#define DB_FASTCALL #endif -/* END MIDIPLAY GLUE */ + +typedef uintptr_t Bitu; +typedef intptr_t Bits; +typedef uint64_t Bit64u; +typedef int64_t Bit64s; +typedef uint32_t Bit32u; +typedef int32_t Bit32s; +typedef uint16_t Bit16u; +typedef int16_t Bit16s; +typedef uint8_t Bit8u; +typedef int8_t Bit8s; //Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume #define WAVE_HANDLER 10 @@ -49,267 +49,236 @@ typedef signed char Bit8s; //Select the type of wave generator routine #define DBOPL_WAVE WAVE_TABLEMUL -#ifdef _WIN32 -# ifdef _MSC_VER -# ifdef _WIN64 -typedef __int64 ssize_t; -# else -typedef __int32 ssize_t; -# endif -# else -# ifdef _WIN64 -typedef int64_t ssize_t; -# else -typedef int32_t ssize_t; -# endif -# endif -#endif - -namespace DBOPL -{ +namespace DBOPL { - struct Chip; - struct Operator; - struct Channel; +struct Chip; +struct Operator; +struct Channel; #if (DBOPL_WAVE == WAVE_HANDLER) - typedef Bits(DB_FASTCALL *WaveHandler)(Bitu i, Bitu volume); +typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); #endif - typedef Bits(DBOPL::Operator::*VolumeHandler)(); - typedef Channel *(DBOPL::Channel::*SynthHandler)(Chip *chip, Bit32u samples, Bit32s *output); - - //Different synth modes that can generate blocks of data - typedef enum - { - sm2AM, - sm2FM, - sm3AM, - sm3FM, - sm4Start, - sm3FMFM, - sm3AMFM, - sm3FMAM, - sm3AMAM, - sm6Start, - sm2Percussion, - sm3Percussion - } SynthMode; - - //Shifts for the values contained in chandata variable - enum - { - SHIFT_KSLBASE = 16, - SHIFT_KEYCODE = 24 - }; - - struct Operator - { - public: - //Masks for operator 20 values - enum - { - MASK_KSR = 0x10, - MASK_SUSTAIN = 0x20, - MASK_VIBRATO = 0x40, - MASK_TREMOLO = 0x80 - }; - - typedef enum - { - OFF, - RELEASE, - SUSTAIN, - DECAY, - ATTACK - } State; - - VolumeHandler volHandler; +typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); +typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output ); + +//Different synth modes that can generate blocks of data +typedef enum { + sm2AM, + sm2FM, + sm3AM, + sm3FM, + sm4Start, + sm3FMFM, + sm3AMFM, + sm3FMAM, + sm3AMAM, + sm6Start, + sm2Percussion, + sm3Percussion, +} SynthMode; + +//Shifts for the values contained in chandata variable +enum { + SHIFT_KSLBASE = 16, + SHIFT_KEYCODE = 24, +}; + +struct Operator { +public: + //Masks for operator 20 values + enum { + MASK_KSR = 0x10, + MASK_SUSTAIN = 0x20, + MASK_VIBRATO = 0x40, + MASK_TREMOLO = 0x80, + }; + + typedef enum { + OFF, + RELEASE, + SUSTAIN, + DECAY, + ATTACK, + } State; + + VolumeHandler volHandler; #if (DBOPL_WAVE == WAVE_HANDLER) - WaveHandler waveHandler; //Routine that generate a wave + WaveHandler waveHandler; //Routine that generate a wave #else - Bit16s *waveBase; - Bit32u waveMask; - Bit32u waveStart; + Bit16s* waveBase; + Bit32u waveMask; + Bit32u waveStart; #endif - Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index - Bit32u waveAdd; //The base frequency without vibrato - Bit32u waveCurrent; //waveAdd + vibratao - - Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this - Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? - Bit32u vibrato; //Scaled up vibrato strength - Bit32s sustainLevel; //When stopping at sustain level stop here - Bit32s totalLevel; //totalLevel is added to every generated volume - Bit32u currentLevel; //totalLevel + tremolo - Bit32s volume; //The currently active volume - - Bit32u attackAdd; //Timers for the different states of the envelope - Bit32u decayAdd; - Bit32u releaseAdd; - Bit32u rateIndex; //Current position of the evenlope - - Bit8u rateZero; //Bits for the different states of the envelope having no changes - Bit8u keyOn; //Bitmask of different values that can generate keyon - //Registers, also used to check for changes - Bit8u reg20, reg40, reg60, reg80, regE0; - //Active part of the envelope we're in - Bit8u state; - //0xff when tremolo is enabled - Bit8u tremoloMask; - //Strength of the vibrato - Bit8u vibStrength; - //Keep track of the calculated KSR so we can check for changes - Bit8u ksr; - private: - void SetState(Bit8u s); - void UpdateAttack(const Chip *chip); - void UpdateRelease(const Chip *chip); - void UpdateDecay(const Chip *chip); - public: - void UpdateAttenuation(); - void UpdateRates(const Chip *chip); - void UpdateFrequency(); - - void Write20(const Chip *chip, Bit8u val); - void Write40(const Chip *chip, Bit8u val); - void Write60(const Chip *chip, Bit8u val); - void Write80(const Chip *chip, Bit8u val); - void WriteE0(const Chip *chip, Bit8u val); - - bool Silent() const; - void Prepare(const Chip *chip); - - void KeyOn(Bit8u mask); - void KeyOff(Bit8u mask); - - template< State state> - Bits TemplateVolume(); - - Bit32s RateForward(Bit32u add); - Bitu ForwardWave(); - Bitu ForwardVolume(); - - Bits GetSample(Bits modulation); - Bits GetWave(Bitu index, Bitu vol); - public: - Operator(); - char ____padding[5]; - }; - - struct Channel - { - Operator op[2]; - inline Operator *Op(Bitu index) - { - return &((this + (index >> 1))->op[ index & 1 ]); - } - SynthHandler synthHandler; - Bit32u chanData; //Frequency/octave and derived values - Bit32s old[2]; //Old data for feedback - - Bit8u feedback; //Feedback shift - Bit8u regB0; //Register values to check for changes - Bit8u regC0; - //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel - Bit8u fourMask; - Bit8s maskLeft; //Sign extended values for both channel's panning - Bit8s maskRight; - - //Forward the channel data to the operators of the channel - void SetChanData(const Chip *chip, Bit32u data); - //Change in the chandata, check for new values and if we have to forward to operators - void UpdateFrequency(const Chip *chip, Bit8u fourOp); - void WriteA0(const Chip *chip, Bit8u val); - void WriteB0(const Chip *chip, Bit8u val); - void WriteC0(const Chip *chip, Bit8u val); - void ResetC0(const Chip *chip); - - //call this for the first channel - template< bool opl3Mode > - void GeneratePercussion(Chip *chip, Bit32s *output); - - //Generate blocks of data in specific modes - template<SynthMode mode> - Channel *BlockTemplate(Chip *chip, Bit32u samples, Bit32s *output); - Channel(); - char ____padding[6]; - }; - - struct Chip - { - //This is used as the base counter for vibrato and tremolo - Bit32u lfoCounter; - Bit32u lfoAdd; - - - Bit32u noiseCounter; - Bit32u noiseAdd; - Bit32u noiseValue; - - //Frequency scales for the different multiplications - Bit32u freqMul[16]; - //Rates for decay and release for rate of this chip - Bit32u linearRates[76]; - //Best match attack rates for the rate of this chip - Bit32u attackRates[76]; - - //18 channels with 2 operators each - Channel chan[18]; - - Bit8u reg104; - Bit8u reg08; - Bit8u reg04; - Bit8u regBD; - Bit8u vibratoIndex; - Bit8u tremoloIndex; - Bit8s vibratoSign; - Bit8u vibratoShift; - Bit8u tremoloValue; - Bit8u vibratoStrength; - Bit8u tremoloStrength; - //Mask for allowed wave forms - Bit8u waveFormMask; - //0 or -1 when enabled - Bit8s opl3Active; - - //Return the maximum amount of samples before and LFO change - Bit32u ForwardLFO(Bit32u samples); - Bit32u ForwardNoise(); - - void WriteBD(Bit8u val); - void WriteReg(Bit32u reg, Bit8u val); - - Bit32u WriteAddr(Bit32u port, Bit8u val); - - void GenerateBlock2(Bitu samples, Bit32s *output); - void GenerateBlock3(Bitu samples, Bit32s *output); - - void GenerateBlock2_Mix(Bitu samples, Bit32s *output); - void GenerateBlock3_Mix(Bitu samples, Bit32s *output); - - void Generate(Bit32u samples); - void Setup(Bit32u r); - - Chip(); - }; - - struct Handler - { - DBOPL::Chip chip; - Bit32u WriteAddr(Bit32u port, Bit8u val); - void WriteReg(Bit32u addr, Bit8u val); - void Generate(void(*AddSamples_m32)(Bitu, Bit32s *), - void(*AddSamples_s32)(Bitu, Bit32s *), - Bitu samples); - void GenerateArr(Bit32s *out, Bitu *samples); - void GenerateArr(Bit32s *out, ssize_t *samples); - void GenerateArr(Bit16s *out, ssize_t *samples); - void GenerateArrMix(Bit32s *out, ssize_t *samples); - void GenerateArrMix(Bit16s *out, ssize_t *samples); - void Init(Bitu rate); - }; - - -} //Namespace + Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index + Bit32u waveAdd; //The base frequency without vibrato + Bit32u waveCurrent; //waveAdd + vibratao + + Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this + Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? + Bit32u vibrato; //Scaled up vibrato strength + Bit32s sustainLevel; //When stopping at sustain level stop here + Bit32s totalLevel; //totalLevel is added to every generated volume + Bit32u currentLevel; //totalLevel + tremolo + Bit32s volume; //The currently active volume + + Bit32u attackAdd; //Timers for the different states of the envelope + Bit32u decayAdd; + Bit32u releaseAdd; + Bit32u rateIndex; //Current position of the evenlope + + Bit8u rateZero; //Bits for the different states of the envelope having no changes + Bit8u keyOn; //Bitmask of different values that can generate keyon + //Registers, also used to check for changes + Bit8u reg20, reg40, reg60, reg80, regE0; + //Active part of the envelope we're in + Bit8u state; + //0xff when tremolo is enabled + Bit8u tremoloMask; + //Strength of the vibrato + Bit8u vibStrength; + //Keep track of the calculated KSR so we can check for changes + Bit8u ksr; +private: + void SetState( Bit8u s ); + void UpdateAttack( const Chip* chip ); + void UpdateRelease( const Chip* chip ); + void UpdateDecay( const Chip* chip ); +public: + void UpdateAttenuation(); + void UpdateRates( const Chip* chip ); + void UpdateFrequency( ); + + void Write20( const Chip* chip, Bit8u val ); + void Write40( const Chip* chip, Bit8u val ); + void Write60( const Chip* chip, Bit8u val ); + void Write80( const Chip* chip, Bit8u val ); + void WriteE0( const Chip* chip, Bit8u val ); + + bool Silent() const; + void Prepare( const Chip* chip ); + + void KeyOn( Bit8u mask); + void KeyOff( Bit8u mask); + + template< State state> + Bits TemplateVolume( ); + + Bit32s RateForward( Bit32u add ); + Bitu ForwardWave(); + Bitu ForwardVolume(); + + Bits GetSample( Bits modulation ); + Bits GetWave( Bitu index, Bitu vol ); +public: + Operator(); +}; + +struct Channel { + Operator op[2]; + inline Operator* Op( Bitu index ) { + return &( ( this + (index >> 1) )->op[ index & 1 ]); + } + SynthHandler synthHandler; + Bit32u chanData; //Frequency/octave and derived values + Bit32s old[2]; //Old data for feedback + + Bit8u feedback; //Feedback shift + Bit8u regB0; //Register values to check for changes + Bit8u regC0; + //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel + Bit8u fourMask; + Bit8s maskLeft; //Sign extended values for both channel's panning + Bit8s maskRight; + + //Forward the channel data to the operators of the channel + void SetChanData( const Chip* chip, Bit32u data ); + //Change in the chandata, check for new values and if we have to forward to operators + void UpdateFrequency( const Chip* chip, Bit8u fourOp ); + void UpdateSynth(const Chip* chip); + void WriteA0( const Chip* chip, Bit8u val ); + void WriteB0( const Chip* chip, Bit8u val ); + void WriteC0( const Chip* chip, Bit8u val ); + + //call this for the first channel + template< bool opl3Mode > + void GeneratePercussion( Chip* chip, Bit32s* output ); + + //Generate blocks of data in specific modes + template<SynthMode mode> + Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ); + Channel(); +}; + +struct Chip { + //This is used as the base counter for vibrato and tremolo + Bit32u lfoCounter; + Bit32u lfoAdd; + + + Bit32u noiseCounter; + Bit32u noiseAdd; + Bit32u noiseValue; + + //Frequency scales for the different multiplications + Bit32u freqMul[16]; + //Rates for decay and release for rate of this chip + Bit32u linearRates[76]; + //Best match attack rates for the rate of this chip + Bit32u attackRates[76]; + + //18 channels with 2 operators each + Channel chan[18]; + + Bit8u reg104; + Bit8u reg08; + Bit8u reg04; + Bit8u regBD; + Bit8u vibratoIndex; + Bit8u tremoloIndex; + Bit8s vibratoSign; + Bit8u vibratoShift; + Bit8u tremoloValue; + Bit8u vibratoStrength; + Bit8u tremoloStrength; + //Mask for allowed wave forms + Bit8u waveFormMask; + //0 or -1 when enabled + Bit8s opl3Active; + + //Return the maximum amount of samples before and LFO change + Bit32u ForwardLFO( Bit32u samples ); + Bit32u ForwardNoise(); + + void WriteBD( Bit8u val ); + void WriteReg(Bit32u reg, Bit8u val ); + + Bit32u WriteAddr( Bit32u port, Bit8u val ); + + void GenerateBlock2( Bitu samples, Bit32s* output ); + void GenerateBlock2_Mix( Bitu samples, Bit32s* output ); + void GenerateBlock3( Bitu samples, Bit32s* output ); + void GenerateBlock3_Mix( Bitu samples, Bit32s* output ); + + //Update the synth handlers in all channels + void UpdateSynths(); + void Generate( Bit32u samples ); + void Setup( Bit32u r ); + + Chip(); +}; + +struct Handler { + DBOPL::Chip chip; + Bit32u WriteAddr( Bit32u port, Bit8u val ); + void WriteReg( Bit32u addr, Bit8u val ); + void GenerateArr(Bit32s *out, Bitu *samples); + void GenerateArr(Bit16s *out, Bitu *samples); + void GenerateArrMix(Bit32s *out, Bitu *samples); + void GenerateArrMix(Bit16s *out, Bitu *samples); + void Init( Bitu rate ); +}; + + +} //Namespace diff --git a/src/chips/dosbox_opl3.cpp b/src/chips/dosbox_opl3.cpp index e748b85..af4cb08 100644 --- a/src/chips/dosbox_opl3.cpp +++ b/src/chips/dosbox_opl3.cpp @@ -1,22 +1,16 @@ #include "dosbox_opl3.h" #include "dosbox/dbopl.h" +#include <new> #include <cstdlib> #include <assert.h> DosBoxOPL3::DosBoxOPL3() : - OPLChipBase(), - m_chip(NULL) + OPLChipBaseBufferedT(), + m_chip(new DBOPL::Handler) { reset(); } -DosBoxOPL3::DosBoxOPL3(const DosBoxOPL3 &c) : - OPLChipBase(c), - m_chip(NULL) -{ - setRate(c.m_rate); -} - DosBoxOPL3::~DosBoxOPL3() { DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); @@ -25,23 +19,20 @@ DosBoxOPL3::~DosBoxOPL3() void DosBoxOPL3::setRate(uint32_t rate) { - OPLChipBase::setRate(rate); - reset(); + OPLChipBaseBufferedT::setRate(rate); + DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); + chip_r->~Handler(); + new(chip_r) DBOPL::Handler; + chip_r->Init(49716); } void DosBoxOPL3::reset() { + OPLChipBaseBufferedT::reset(); DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); - if(m_chip && chip_r) - delete chip_r; - m_chip = new DBOPL::Handler; - chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); - chip_r->Init(m_rate); -} - -void DosBoxOPL3::reset(uint32_t rate) -{ - setRate(rate); + chip_r->~Handler(); + new(chip_r) DBOPL::Handler; + chip_r->Init(49716); } void DosBoxOPL3::writeReg(uint16_t addr, uint8_t data) @@ -50,63 +41,14 @@ void DosBoxOPL3::writeReg(uint16_t addr, uint8_t data) chip_r->WriteReg(static_cast<Bit32u>(addr), data); } -int DosBoxOPL3::generate(int16_t *output, size_t frames) -{ - DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); - ssize_t left = (ssize_t)frames; - while(left > 0) - { - ssize_t frames_i = left; - chip_r->GenerateArr(output, &frames_i); - output += (frames_i * 2); - left -= frames_i; - } - return (int)frames; -} - -int DosBoxOPL3::generateAndMix(int16_t *output, size_t frames) -{ - DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); - ssize_t left = (ssize_t)frames; - while(left > 0) - { - ssize_t frames_i = left; - chip_r->GenerateArrMix(output, &frames_i); - output += (frames_i * 2); - left -= frames_i; - } - return (int)frames; -} - -int DosBoxOPL3::generate32(int32_t *output, size_t frames) -{ - DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); - ssize_t left = (ssize_t)frames; - while(left > 0) - { - ssize_t frames_i = left; - chip_r->GenerateArr(output, &frames_i); - output += (frames_i * 2); - left -= frames_i; - } - return (int)frames; -} - -int DosBoxOPL3::generateAndMix32(int32_t *output, size_t frames) +void DosBoxOPL3::nativeGenerateN(int16_t *output, size_t frames) { DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip); - ssize_t left = (ssize_t)frames; - while(left > 0) - { - ssize_t frames_i = left; - chip_r->GenerateArrMix(output, &frames_i); - output += (frames_i * 2); - left -= frames_i; - } - return (int)frames; + Bitu frames_i = frames; + chip_r->GenerateArr(output, &frames_i); } const char *DosBoxOPL3::emulatorName() { - return "DosBox 0.74 OPL3"; + return "DosBox 0.74-r4111 OPL3"; } diff --git a/src/chips/dosbox_opl3.h b/src/chips/dosbox_opl3.h index 422e2d1..f4c68da 100644 --- a/src/chips/dosbox_opl3.h +++ b/src/chips/dosbox_opl3.h @@ -3,23 +3,20 @@ #include "opl_chip_base.h" -class DosBoxOPL3 final : public OPLChipBase +class DosBoxOPL3 final : public OPLChipBaseBufferedT<DosBoxOPL3> { void *m_chip; public: DosBoxOPL3(); - DosBoxOPL3(const DosBoxOPL3 &c); - virtual ~DosBoxOPL3() override; + ~DosBoxOPL3() override; - virtual void setRate(uint32_t rate) override; - virtual void reset() override; - virtual void reset(uint32_t rate) override; - virtual void writeReg(uint16_t addr, uint8_t data) override; - virtual int generate(int16_t *output, size_t frames) override; - virtual int generateAndMix(int16_t *output, size_t frames) override; - virtual int generate32(int32_t *output, size_t frames) override; - virtual int generateAndMix32(int32_t *output, size_t frames) override; - virtual const char *emulatorName() override; + void setRate(uint32_t rate) override; + void reset() override; + void writeReg(uint16_t addr, uint8_t data) override; + void nativePreGenerate() override {} + void nativePostGenerate() override {} + void nativeGenerateN(int16_t *output, size_t frames) override; + const char *emulatorName() override; }; #endif // DOSBOX_OPL3_H diff --git a/src/chips/nuked/nukedopl3.c b/src/chips/nuked/nukedopl3.c index eadb6b9..87d3212 100644 --- a/src/chips/nuked/nukedopl3.c +++ b/src/chips/nuked/nukedopl3.c @@ -697,18 +697,18 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - channel6->out[0] = &channel6->slots[1]->out; - channel6->out[1] = &channel6->slots[1]->out; + channel6->out[0] = &channel6->slotz[1]->out; + channel6->out[1] = &channel6->slotz[1]->out; channel6->out[2] = &chip->zeromod; channel6->out[3] = &chip->zeromod; - channel7->out[0] = &channel7->slots[0]->out; - channel7->out[1] = &channel7->slots[0]->out; - channel7->out[2] = &channel7->slots[1]->out; - channel7->out[3] = &channel7->slots[1]->out; - channel8->out[0] = &channel8->slots[0]->out; - channel8->out[1] = &channel8->slots[0]->out; - channel8->out[2] = &channel8->slots[1]->out; - channel8->out[3] = &channel8->slots[1]->out; + channel7->out[0] = &channel7->slotz[0]->out; + channel7->out[1] = &channel7->slotz[0]->out; + channel7->out[2] = &channel7->slotz[1]->out; + channel7->out[3] = &channel7->slotz[1]->out; + channel8->out[0] = &channel8->slotz[0]->out; + channel8->out[1] = &channel8->slotz[0]->out; + channel8->out[2] = &channel8->slotz[1]->out; + channel8->out[3] = &channel8->slotz[1]->out; for (chnum = 6; chnum < 9; chnum++) { chip->channel[chnum].chtype = ch_drum; @@ -719,49 +719,49 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) /* hh */ if (chip->rhy & 0x01) { - OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel7->slotz[0], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel7->slotz[0], egk_drum); } /* tc */ if (chip->rhy & 0x02) { - OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel8->slotz[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel8->slotz[1], egk_drum); } /* tom */ if (chip->rhy & 0x04) { - OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel8->slotz[0], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel8->slotz[0], egk_drum); } /* sd */ if (chip->rhy & 0x08) { - OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel7->slotz[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel7->slotz[1], egk_drum); } /* bd */ if (chip->rhy & 0x10) { - OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slotz[0], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slotz[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slotz[0], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slotz[1], egk_drum); } } else @@ -770,8 +770,8 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) { chip->channel[chnum].chtype = ch_2op; OPL3_ChannelSetupAlg(&chip->channel[chnum]); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[0], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[1], egk_drum); } } } @@ -785,14 +785,14 @@ static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) channel->f_num = (channel->f_num & 0x300) | data; channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->slotz[1]); if (channel->chip->newm && channel->chtype == ch_4op) { channel->pair->f_num = channel->f_num; channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]); } } @@ -806,15 +806,15 @@ static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) channel->block = (data >> 2) & 0x07; channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->slotz[1]); if (channel->chip->newm && channel->chtype == ch_4op) { channel->pair->f_num = channel->f_num; channel->pair->block = channel->block; channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]); } } @@ -824,19 +824,19 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel) { if (channel->ch_num == 7 || channel->ch_num == 8) { - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->chip->zeromod; + channel->slotz[1]->mod = &channel->chip->zeromod; return; } switch (channel->alg & 0x01) { case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->slotz[0]->out; break; case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->chip->zeromod; break; } return; @@ -854,43 +854,43 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel) switch (channel->alg & 0x03) { case 0x00: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out; + channel->slotz[0]->mod = &channel->pair->slotz[1]->out; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->slotz[1]->out; channel->out[1] = &channel->chip->zeromod; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x01: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[1]->out; - channel->out[1] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out; + channel->slotz[0]->mod = &channel->chip->zeromod; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->pair->slotz[1]->out; + channel->out[1] = &channel->slotz[1]->out; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x02: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->pair->slotz[1]->out; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->pair->slotz[0]->out; + channel->out[1] = &channel->slotz[1]->out; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x03: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[0]->out; - channel->out[2] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->pair->slotz[1]->out; + channel->slotz[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->pair->slotz[0]->out; + channel->out[1] = &channel->slotz[0]->out; + channel->out[2] = &channel->slotz[1]->out; channel->out[3] = &channel->chip->zeromod; break; } @@ -900,18 +900,18 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel) switch (channel->alg & 0x01) { case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->slotz[1]->out; channel->out[1] = &channel->chip->zeromod; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->slotz[0]->out; + channel->out[1] = &channel->slotz[1]->out; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; @@ -964,21 +964,21 @@ static void OPL3_ChannelKeyOn(opl3_channel *channel) { if (channel->chtype == ch_4op) { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slotz[1], egk_norm); } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm); } } else { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm); } } @@ -988,21 +988,21 @@ static void OPL3_ChannelKeyOff(opl3_channel *channel) { if (channel->chtype == ch_4op) { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slotz[1], egk_norm); } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm); } } else { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm); } } @@ -1147,7 +1147,7 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf) if (chip->eg_timerrem || chip->eg_state) { - if (chip->eg_timer == 0xfffffffff) + if (chip->eg_timer == (uint64_t)0xfffffffffU) { chip->eg_timer = 0; chip->eg_timerrem = 1; @@ -1209,8 +1209,8 @@ void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) } for (channum = 0; channum < 18; channum++) { - chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]]; - chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3]; + chip->channel[channum].slotz[0] = &chip->slot[ch_slot[channum]]; + chip->channel[channum].slotz[1] = &chip->slot[ch_slot[channum] + 3]; chip->slot[ch_slot[channum]].channel = &chip->channel[channum]; chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum]; if ((channum % 9) < 3) diff --git a/src/chips/nuked/nukedopl3.h b/src/chips/nuked/nukedopl3.h index ce748b1..d57cf5f 100644 --- a/src/chips/nuked/nukedopl3.h +++ b/src/chips/nuked/nukedopl3.h @@ -86,7 +86,7 @@ struct _opl3_slot { }; struct _opl3_channel { - opl3_slot *slots[2]; + opl3_slot *slotz[2];/*Don't use "slots" keyword to avoid conflict with Qt applications*/ opl3_channel *pair; opl3_chip *chip; Bit16s *out[4]; diff --git a/src/chips/nuked/nukedopl3_174.c b/src/chips/nuked/nukedopl3_174.c index 401089c..99eab16 100644 --- a/src/chips/nuked/nukedopl3_174.c +++ b/src/chips/nuked/nukedopl3_174.c @@ -638,18 +638,18 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - channel6->out[0] = &channel6->slots[1]->out; - channel6->out[1] = &channel6->slots[1]->out; + channel6->out[0] = &channel6->slotz[1]->out; + channel6->out[1] = &channel6->slotz[1]->out; channel6->out[2] = &chip->zeromod; channel6->out[3] = &chip->zeromod; - channel7->out[0] = &channel7->slots[0]->out; - channel7->out[1] = &channel7->slots[0]->out; - channel7->out[2] = &channel7->slots[1]->out; - channel7->out[3] = &channel7->slots[1]->out; - channel8->out[0] = &channel8->slots[0]->out; - channel8->out[1] = &channel8->slots[0]->out; - channel8->out[2] = &channel8->slots[1]->out; - channel8->out[3] = &channel8->slots[1]->out; + channel7->out[0] = &channel7->slotz[0]->out; + channel7->out[1] = &channel7->slotz[0]->out; + channel7->out[2] = &channel7->slotz[1]->out; + channel7->out[3] = &channel7->slotz[1]->out; + channel8->out[0] = &channel8->slotz[0]->out; + channel8->out[1] = &channel8->slotz[0]->out; + channel8->out[2] = &channel8->slotz[1]->out; + channel8->out[3] = &channel8->slotz[1]->out; for (chnum = 6; chnum < 9; chnum++) { chip->channel[chnum].chtype = ch_drum; @@ -658,49 +658,49 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) /*hh*/ if (chip->rhy & 0x01) { - OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel7->slotz[0], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel7->slotz[0], egk_drum); } /*tc*/ if (chip->rhy & 0x02) { - OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel8->slotz[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel8->slotz[1], egk_drum); } /*tom*/ if (chip->rhy & 0x04) { - OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel8->slotz[0], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel8->slotz[0], egk_drum); } /*sd*/ if (chip->rhy & 0x08) { - OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel7->slotz[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel7->slotz[1], egk_drum); } /*bd*/ if (chip->rhy & 0x10) { - OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slotz[0], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slotz[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slotz[0], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slotz[1], egk_drum); } } else @@ -709,8 +709,8 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) { chip->channel[chnum].chtype = ch_2op; OPL3_ChannelSetupAlg(&chip->channel[chnum]); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[0], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[1], egk_drum); } } } @@ -724,18 +724,18 @@ static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) channel->f_num = (channel->f_num & 0x300) | data; channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - OPL3_EnvelopeUpdateRate(channel->slots[0]); - OPL3_EnvelopeUpdateRate(channel->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->slotz[1]); + OPL3_EnvelopeUpdateRate(channel->slotz[0]); + OPL3_EnvelopeUpdateRate(channel->slotz[1]); if (channel->chip->newm && channel->chtype == ch_4op) { channel->pair->f_num = channel->f_num; channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); - OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slotz[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slotz[1]); } } @@ -749,19 +749,19 @@ static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) channel->block = (data >> 2) & 0x07; channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - OPL3_EnvelopeUpdateRate(channel->slots[0]); - OPL3_EnvelopeUpdateRate(channel->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->slotz[1]); + OPL3_EnvelopeUpdateRate(channel->slotz[0]); + OPL3_EnvelopeUpdateRate(channel->slotz[1]); if (channel->chip->newm && channel->chtype == ch_4op) { channel->pair->f_num = channel->f_num; channel->pair->block = channel->block; channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); - OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slotz[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slotz[1]); } } @@ -772,12 +772,12 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel) switch (channel->alg & 0x01) { case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->slotz[0]->out; break; case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->chip->zeromod; break; } return; @@ -795,43 +795,43 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel) switch (channel->alg & 0x03) { case 0x00: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out; + channel->slotz[0]->mod = &channel->pair->slotz[1]->out; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->slotz[1]->out; channel->out[1] = &channel->chip->zeromod; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x01: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[1]->out; - channel->out[1] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out; + channel->slotz[0]->mod = &channel->chip->zeromod; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->pair->slotz[1]->out; + channel->out[1] = &channel->slotz[1]->out; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x02: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->pair->slotz[1]->out; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->pair->slotz[0]->out; + channel->out[1] = &channel->slotz[1]->out; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x03: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[0]->out; - channel->out[2] = &channel->slots[1]->out; + channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod; + channel->pair->slotz[1]->mod = &channel->chip->zeromod; + channel->slotz[0]->mod = &channel->pair->slotz[1]->out; + channel->slotz[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->pair->slotz[0]->out; + channel->out[1] = &channel->slotz[0]->out; + channel->out[2] = &channel->slotz[1]->out; channel->out[3] = &channel->chip->zeromod; break; } @@ -841,18 +841,18 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel) switch (channel->alg & 0x01) { case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->slotz[0]->out; + channel->out[0] = &channel->slotz[1]->out; channel->out[1] = &channel->chip->zeromod; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; + channel->slotz[0]->mod = &channel->slotz[0]->fbmod; + channel->slotz[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->slotz[0]->out; + channel->out[1] = &channel->slotz[1]->out; channel->out[2] = &channel->chip->zeromod; channel->out[3] = &channel->chip->zeromod; break; @@ -905,21 +905,21 @@ static void OPL3_ChannelKeyOn(opl3_channel *channel) { if (channel->chtype == ch_4op) { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slotz[1], egk_norm); } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm); } } else { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm); } } @@ -929,21 +929,21 @@ static void OPL3_ChannelKeyOff(opl3_channel *channel) { if (channel->chtype == ch_4op) { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slotz[1], egk_norm); } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm); } } else { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm); } } @@ -997,9 +997,9 @@ static void OPL3_GenerateRhythm1(opl3_chip *chip) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - OPL3_SlotGenerate(channel6->slots[0]); - phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; - phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + OPL3_SlotGenerate(channel6->slotz[0]); + phase14 = (channel7->slotz[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slotz[1]->pg_phase >> 9) & 0x3ff; phase = 0x00; /*hh tc phase bit*/ phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) @@ -1007,9 +1007,9 @@ static void OPL3_GenerateRhythm1(opl3_chip *chip) /*hh*/ phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01)) << 1)); - OPL3_SlotGeneratePhase(channel7->slots[0], phase); + OPL3_SlotGeneratePhase(channel7->slotz[0], phase); /*tt*/ - OPL3_SlotGenerateZM(channel8->slots[0]); + OPL3_SlotGenerateZM(channel8->slotz[0]); } static void OPL3_GenerateRhythm2(opl3_chip *chip) @@ -1025,19 +1025,19 @@ static void OPL3_GenerateRhythm2(opl3_chip *chip) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - OPL3_SlotGenerate(channel6->slots[1]); - phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; - phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + OPL3_SlotGenerate(channel6->slotz[1]); + phase14 = (channel7->slotz[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slotz[1]->pg_phase >> 9) & 0x3ff; phase = 0x00; /*hh tc phase bit*/ phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; /*sd*/ phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); - OPL3_SlotGeneratePhase(channel7->slots[1], phase); + OPL3_SlotGeneratePhase(channel7->slotz[1], phase); /*tc*/ phase = 0x100 | (phasebit << 9); - OPL3_SlotGeneratePhase(channel8->slots[1], phase); + OPL3_SlotGeneratePhase(channel8->slotz[1], phase); } void OPL3v17_Generate(opl3_chip *chip, Bit16s *buf) @@ -1202,8 +1202,8 @@ void OPL3v17_Reset(opl3_chip *chip, Bit32u samplerate) } for (channum = 0; channum < 18; channum++) { - chip->channel[channum].slots[0] = &chip->chipslot[ch_slot[channum]]; - chip->channel[channum].slots[1] = &chip->chipslot[ch_slot[channum] + 3]; + chip->channel[channum].slotz[0] = &chip->chipslot[ch_slot[channum]]; + chip->channel[channum].slotz[1] = &chip->chipslot[ch_slot[channum] + 3]; chip->chipslot[ch_slot[channum]].channel = &chip->channel[channum]; chip->chipslot[ch_slot[channum] + 3].channel = &chip->channel[channum]; if ((channum % 9) < 3) diff --git a/src/chips/nuked/nukedopl3_174.h b/src/chips/nuked/nukedopl3_174.h index 43e4a6e..240802f 100644 --- a/src/chips/nuked/nukedopl3_174.h +++ b/src/chips/nuked/nukedopl3_174.h @@ -91,7 +91,7 @@ struct _opl3_slot { }; struct _opl3_channel { - opl3_slot *slots[2]; + opl3_slot *slotz[2];/*Don't use "slots" keyword to avoid conflict with Qt applications*/ opl3_channel *pair; opl3_chip *chip; Bit16s *out[4]; diff --git a/src/chips/nuked_opl3.cpp b/src/chips/nuked_opl3.cpp index 70fc525..48e5c17 100644 --- a/src/chips/nuked_opl3.cpp +++ b/src/chips/nuked_opl3.cpp @@ -3,18 +3,10 @@ #include <cstring> NukedOPL3::NukedOPL3() : - OPLChipBase() + OPLChipBaseT() { m_chip = new opl3_chip; - reset(m_rate); -} - -NukedOPL3::NukedOPL3(const NukedOPL3 &c): - OPLChipBase(c) -{ - m_chip = new opl3_chip; - std::memset(m_chip, 0, sizeof(opl3_chip)); - reset(c.m_rate); + setRate(m_rate); } NukedOPL3::~NukedOPL3() @@ -25,7 +17,7 @@ NukedOPL3::~NukedOPL3() void NukedOPL3::setRate(uint32_t rate) { - OPLChipBase::setRate(rate); + OPLChipBaseT::setRate(rate); opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); std::memset(chip_r, 0, sizeof(opl3_chip)); OPL3_Reset(chip_r, rate); @@ -33,12 +25,10 @@ void NukedOPL3::setRate(uint32_t rate) void NukedOPL3::reset() { - setRate(m_rate); -} - -void NukedOPL3::reset(uint32_t rate) -{ - setRate(rate); + OPLChipBaseT::reset(); + opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); + std::memset(chip_r, 0, sizeof(opl3_chip)); + OPL3_Reset(chip_r, m_rate); } void NukedOPL3::writeReg(uint16_t addr, uint8_t data) @@ -47,44 +37,10 @@ void NukedOPL3::writeReg(uint16_t addr, uint8_t data) OPL3_WriteRegBuffered(chip_r, addr, data); } -int NukedOPL3::generate(int16_t *output, size_t frames) -{ - opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - OPL3_GenerateStream(chip_r, output, (Bit32u)frames); - return (int)frames; -} - -int NukedOPL3::generateAndMix(int16_t *output, size_t frames) -{ - opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - OPL3_GenerateStreamMix(chip_r, output, (Bit32u)frames); - return (int)frames; -} - -int NukedOPL3::generate32(int32_t *output, size_t frames) -{ - opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - for(size_t i = 0; i < frames; ++i) { - int16_t frame[2]; - OPL3_GenerateResampled(chip_r, frame); - output[0] = (int32_t)frame[0]; - output[1] = (int32_t)frame[1]; - output += 2; - } - return (int)frames; -} - -int NukedOPL3::generateAndMix32(int32_t *output, size_t frames) +void NukedOPL3::nativeGenerate(int16_t *frame) { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - for(size_t i = 0; i < frames; ++i) { - int16_t frame[2]; - OPL3_GenerateResampled(chip_r, frame); - output[0] += (int32_t)frame[0]; - output[1] += (int32_t)frame[1]; - output += 2; - } - return (int)frames; + OPL3_Generate(chip_r, frame); } const char *NukedOPL3::emulatorName() diff --git a/src/chips/nuked_opl3.h b/src/chips/nuked_opl3.h index ceb1dfd..25d9ed5 100644 --- a/src/chips/nuked_opl3.h +++ b/src/chips/nuked_opl3.h @@ -3,23 +3,20 @@ #include "opl_chip_base.h" -class NukedOPL3 final : public OPLChipBase +class NukedOPL3 final : public OPLChipBaseT<NukedOPL3> { void *m_chip; public: NukedOPL3(); - NukedOPL3(const NukedOPL3 &c); - virtual ~NukedOPL3() override; + ~NukedOPL3() override; - virtual void setRate(uint32_t rate) override; - virtual void reset() override; - virtual void reset(uint32_t rate) override; - virtual void writeReg(uint16_t addr, uint8_t data) override; - virtual int generate(int16_t *output, size_t frames) override; - virtual int generateAndMix(int16_t *output, size_t frames) override; - virtual int generate32(int32_t *output, size_t frames) override; - virtual int generateAndMix32(int32_t *output, size_t frames) override; - virtual const char *emulatorName() override; + void setRate(uint32_t rate) override; + void reset() override; + void writeReg(uint16_t addr, uint8_t data) override; + void nativePreGenerate() override {} + void nativePostGenerate() override {} + void nativeGenerate(int16_t *frame) override; + const char *emulatorName() override; }; #endif // NUKED_OPL3_H diff --git a/src/chips/nuked_opl3_v174.cpp b/src/chips/nuked_opl3_v174.cpp index 0dcf925..e24b2e7 100644 --- a/src/chips/nuked_opl3_v174.cpp +++ b/src/chips/nuked_opl3_v174.cpp @@ -3,18 +3,10 @@ #include <cstring> NukedOPL3v174::NukedOPL3v174() : - OPLChipBase() + OPLChipBaseT() { m_chip = new opl3_chip; - reset(m_rate); -} - -NukedOPL3v174::NukedOPL3v174(const NukedOPL3v174 &c): - OPLChipBase(c) -{ - m_chip = new opl3_chip; - std::memset(m_chip, 0, sizeof(opl3_chip)); - reset(c.m_rate); + setRate(m_rate); } NukedOPL3v174::~NukedOPL3v174() @@ -25,7 +17,7 @@ NukedOPL3v174::~NukedOPL3v174() void NukedOPL3v174::setRate(uint32_t rate) { - OPLChipBase::setRate(rate); + OPLChipBaseT::setRate(rate); opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); std::memset(chip_r, 0, sizeof(opl3_chip)); OPL3v17_Reset(chip_r, rate); @@ -33,12 +25,10 @@ void NukedOPL3v174::setRate(uint32_t rate) void NukedOPL3v174::reset() { - setRate(m_rate); -} - -void NukedOPL3v174::reset(uint32_t rate) -{ - setRate(rate); + OPLChipBaseT::reset(); + opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); + std::memset(chip_r, 0, sizeof(opl3_chip)); + OPL3v17_Reset(chip_r, m_rate); } void NukedOPL3v174::writeReg(uint16_t addr, uint8_t data) @@ -47,44 +37,10 @@ void NukedOPL3v174::writeReg(uint16_t addr, uint8_t data) OPL3v17_WriteReg(chip_r, addr, data); } -int NukedOPL3v174::generate(int16_t *output, size_t frames) -{ - opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - OPL3v17_GenerateStream(chip_r, output, (Bit32u)frames); - return (int)frames; -} - -int NukedOPL3v174::generateAndMix(int16_t *output, size_t frames) -{ - opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - OPL3v17_GenerateStreamMix(chip_r, output, (Bit32u)frames); - return (int)frames; -} - -int NukedOPL3v174::generate32(int32_t *output, size_t frames) -{ - opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - for(size_t i = 0; i < frames; ++i) { - int16_t frame[2]; - OPL3v17_GenerateResampled(chip_r, frame); - output[0] = (int32_t)frame[0]; - output[1] = (int32_t)frame[1]; - output += 2; - } - return (int)frames; -} - -int NukedOPL3v174::generateAndMix32(int32_t *output, size_t frames) +void NukedOPL3v174::nativeGenerate(int16_t *frame) { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); - for(size_t i = 0; i < frames; ++i) { - int16_t frame[2]; - OPL3v17_GenerateResampled(chip_r, frame); - output[0] += (int32_t)frame[0]; - output[1] += (int32_t)frame[1]; - output += 2; - } - return (int)frames; + OPL3v17_Generate(chip_r, frame); } const char *NukedOPL3v174::emulatorName() diff --git a/src/chips/nuked_opl3_v174.h b/src/chips/nuked_opl3_v174.h index acbdcca..b9c5ba6 100644 --- a/src/chips/nuked_opl3_v174.h +++ b/src/chips/nuked_opl3_v174.h @@ -3,23 +3,20 @@ #include "opl_chip_base.h" -class NukedOPL3v174 final : public OPLChipBase +class NukedOPL3v174 final : public OPLChipBaseT<NukedOPL3v174> { void *m_chip; public: NukedOPL3v174(); - NukedOPL3v174(const NukedOPL3v174 &c); - virtual ~NukedOPL3v174() override; + ~NukedOPL3v174() override; - virtual void setRate(uint32_t rate) override; - virtual void reset() override; - virtual void reset(uint32_t rate) override; - virtual void writeReg(uint16_t addr, uint8_t data) override; - virtual int generate(int16_t *output, size_t frames) override; - virtual int generateAndMix(int16_t *output, size_t frames) override; - virtual int generate32(int32_t *output, size_t frames) override; - virtual int generateAndMix32(int32_t *output, size_t frames) override; - virtual const char *emulatorName() override; + void setRate(uint32_t rate) override; + void reset() override; + void writeReg(uint16_t addr, uint8_t data) override; + void nativePreGenerate() override {} + void nativePostGenerate() override {} + void nativeGenerate(int16_t *frame) override; + const char *emulatorName() override; }; #endif // NUKED_OPL3174_H diff --git a/src/chips/opl_chip_base.cpp b/src/chips/opl_chip_base.cpp deleted file mode 100644 index 670a998..0000000 --- a/src/chips/opl_chip_base.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "opl_chip_base.h" - -OPLChipBase::OPLChipBase() : - m_rate(44100) -{} - -OPLChipBase::OPLChipBase(const OPLChipBase &c): - m_rate(c.m_rate) -{} - -OPLChipBase::~OPLChipBase() -{} - -void OPLChipBase::setRate(uint32_t rate) -{ - m_rate = rate; -} - -void OPLChipBase::reset(uint32_t rate) -{ - setRate(rate); -} - -int OPLChipBase::generate32(int32_t *output, size_t frames) -{ - enum { maxFramesAtOnce = 256 }; - int16_t temp[2 * maxFramesAtOnce]; - for(size_t left = frames; left > 0;) { - size_t count = (left < static_cast<size_t>(maxFramesAtOnce)) ? left : static_cast<size_t>(maxFramesAtOnce); - generate(temp, count); - for(size_t i = 0; i < 2 * count; ++i) - output[i] = temp[i]; - left -= count; - output += 2 * count; - } - return (int)frames; -} - -int OPLChipBase::generateAndMix32(int32_t *output, size_t frames) -{ - enum { maxFramesAtOnce = 256 }; - int16_t temp[2 * maxFramesAtOnce]; - for(size_t left = frames; left > 0;) { - size_t count = (left < static_cast<size_t>(maxFramesAtOnce)) ? left : static_cast<size_t>(maxFramesAtOnce); - generate(temp, count); - for(size_t i = 0; i < 2 * count; ++i) - output[i] += temp[i]; - left -= count; - output += 2 * count; - } - return (int)frames; -} diff --git a/src/chips/opl_chip_base.h b/src/chips/opl_chip_base.h index fb9b9e9..5721a81 100644 --- a/src/chips/opl_chip_base.h +++ b/src/chips/opl_chip_base.h @@ -9,24 +9,91 @@ #define override #endif +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) +class VResampler; +#endif + class OPLChipBase { protected: uint32_t m_rate; public: OPLChipBase(); - OPLChipBase(const OPLChipBase &c); virtual ~OPLChipBase(); - virtual void setRate(uint32_t rate); + virtual void setRate(uint32_t rate) = 0; virtual void reset() = 0; - virtual void reset(uint32_t rate); virtual void writeReg(uint16_t addr, uint8_t data) = 0; - virtual int generate(int16_t *output, size_t frames) = 0; - virtual int generateAndMix(int16_t *output, size_t frames) = 0; - virtual int generate32(int32_t *output, size_t frames); - virtual int generateAndMix32(int32_t *output, size_t frames); + + virtual void nativePreGenerate() = 0; + virtual void nativePostGenerate() = 0; + virtual void nativeGenerate(int16_t *frame) = 0; + + virtual void generate(int16_t *output, size_t frames) = 0; + virtual void generateAndMix(int16_t *output, size_t frames) = 0; + virtual void generate32(int32_t *output, size_t frames) = 0; + virtual void generateAndMix32(int32_t *output, size_t frames) = 0; + virtual const char* emulatorName() = 0; +private: + OPLChipBase(const OPLChipBase &c); + OPLChipBase &operator=(const OPLChipBase &c); +}; + +// A base class providing F-bounded generic and efficient implementations, +// supporting resampling of chip outputs +template <class T> +class OPLChipBaseT : public OPLChipBase +{ +public: + OPLChipBaseT(); + virtual ~OPLChipBaseT(); + + virtual void setRate(uint32_t rate) override; + virtual void reset() override; + void generate(int16_t *output, size_t frames) override; + void generateAndMix(int16_t *output, size_t frames) override; + void generate32(int32_t *output, size_t frames) override; + void generateAndMix32(int32_t *output, size_t frames) override; +private: + void setupResampler(uint32_t rate); + void resetResampler(); + void resampledGenerate(int32_t *output); +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + VResampler *m_resampler; +#else + int32_t m_oldsamples[2]; + int32_t m_samples[2]; + int32_t m_samplecnt; + int32_t m_rateratio; + enum { rsm_frac = 10 }; +#endif + // amplitude scale factors in and out of resampler, varying for chips; + // values are OK to "redefine", the static polymorphism will accept it. + enum { resamplerPreAmplify = 1, resamplerPostAttenuate = 1 }; +}; + +// A base class which provides frame-by-frame interfaces on emulations which +// don't have a routine for it. It produces outputs in fixed size buffers. +// Fast register updates will suffer some latency because of buffering. +template <class T, unsigned Buffer = 256> +class OPLChipBaseBufferedT : public OPLChipBaseT<T> +{ +public: + OPLChipBaseBufferedT() + : OPLChipBaseT<T>(), m_bufferIndex(0) {} + virtual ~OPLChipBaseBufferedT() + {} +public: + void reset() override; + void nativeGenerate(int16_t *frame) override; +protected: + virtual void nativeGenerateN(int16_t *output, size_t frames) = 0; +private: + unsigned m_bufferIndex; + int16_t m_buffer[2 * Buffer]; }; +#include "opl_chip_base.tcc" + #endif // ONP_CHIP_BASE_H diff --git a/src/chips/opl_chip_base.tcc b/src/chips/opl_chip_base.tcc new file mode 100644 index 0000000..58145bc --- /dev/null +++ b/src/chips/opl_chip_base.tcc @@ -0,0 +1,216 @@ +#include "opl_chip_base.h" +#include <cmath> + +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) +#include <zita-resampler/vresampler.h> +#endif + +/* OPLChipBase */ + +inline OPLChipBase::OPLChipBase() : + m_rate(44100) +{ +} + +inline OPLChipBase::~OPLChipBase() +{ +} + +/* OPLChipBaseT */ + +template <class T> +OPLChipBaseT<T>::OPLChipBaseT() + : OPLChipBase() +{ +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + m_resampler = new VResampler; +#endif + setupResampler(m_rate); +} + +template <class T> +OPLChipBaseT<T>::~OPLChipBaseT() +{ +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + delete m_resampler; +#endif +} + +template <class T> +void OPLChipBaseT<T>::setRate(uint32_t rate) +{ + uint32_t oldRate = m_rate; + m_rate = rate; + if(rate != oldRate) + setupResampler(rate); + else + resetResampler(); +} + +template <class T> +void OPLChipBaseT<T>::reset() +{ + resetResampler(); +} + +template <class T> +void OPLChipBaseT<T>::generate(int16_t *output, size_t frames) +{ + static_cast<T *>(this)->nativePreGenerate(); + for(size_t i = 0; i < frames; ++i) + { + int32_t frame[2]; + static_cast<T *>(this)->resampledGenerate(frame); + for (unsigned c = 0; c < 2; ++c) { + int32_t temp = frame[c]; + temp = (temp > -32768) ? temp : -32768; + temp = (temp < 32767) ? temp : 32767; + output[c] = (int16_t)temp; + } + output += 2; + } + static_cast<T *>(this)->nativePostGenerate(); +} + +template <class T> +void OPLChipBaseT<T>::generateAndMix(int16_t *output, size_t frames) +{ + static_cast<T *>(this)->nativePreGenerate(); + for(size_t i = 0; i < frames; ++i) + { + int32_t frame[2]; + static_cast<T *>(this)->resampledGenerate(frame); + for (unsigned c = 0; c < 2; ++c) { + int32_t temp = (int32_t)output[c] + frame[c]; + temp = (temp > -32768) ? temp : -32768; + temp = (temp < 32767) ? temp : 32767; + output[c] = (int16_t)temp; + } + output += 2; + } + static_cast<T *>(this)->nativePostGenerate(); +} + +template <class T> +void OPLChipBaseT<T>::generate32(int32_t *output, size_t frames) +{ + static_cast<T *>(this)->nativePreGenerate(); + for(size_t i = 0; i < frames; ++i) + { + static_cast<T *>(this)->resampledGenerate(output); + output += 2; + } + static_cast<T *>(this)->nativePostGenerate(); +} + +template <class T> +void OPLChipBaseT<T>::generateAndMix32(int32_t *output, size_t frames) +{ + static_cast<T *>(this)->nativePreGenerate(); + for(size_t i = 0; i < frames; ++i) + { + int32_t frame[2]; + static_cast<T *>(this)->resampledGenerate(frame); + output[0] += frame[0]; + output[1] += frame[1]; + output += 2; + } + static_cast<T *>(this)->nativePostGenerate(); +} + +template <class T> +void OPLChipBaseT<T>::setupResampler(uint32_t rate) +{ +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + m_resampler->setup(rate * (1.0 / 49716), 2, 48); +#else + m_oldsamples[0] = m_oldsamples[1] = 0; + m_samples[0] = m_samples[1] = 0; + m_samplecnt = 0; + m_rateratio = (int32_t)((rate << rsm_frac) / 49716); +#endif +} + +template <class T> +void OPLChipBaseT<T>::resetResampler() +{ +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + m_resampler->reset(); +#else + m_oldsamples[0] = m_oldsamples[1] = 0; + m_samples[0] = m_samples[1] = 0; + m_samplecnt = 0; +#endif +} + +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) +template <class T> +void OPLChipBaseT<T>::resampledGenerate(int32_t *output) +{ + VResampler *rsm = m_resampler; + float scale = (float)T::resamplerPreAmplify / + (float)T::resamplerPostAttenuate; + float f_in[2]; + float f_out[2]; + rsm->inp_count = 0; + rsm->inp_data = f_in; + rsm->out_count = 1; + rsm->out_data = f_out; + while(rsm->process(), rsm->out_count != 0) + { + int16_t in[2]; + static_cast<T *>(this)->nativeGenerate(in); + f_in[0] = scale * (float)in[0]; + f_in[1] = scale * (float)in[1]; + rsm->inp_count = 1; + rsm->inp_data = f_in; + rsm->out_count = 1; + rsm->out_data = f_out; + } + output[0] = std::lround(f_out[0]); + output[1] = std::lround(f_out[1]); +} +#else +template <class T> +void OPLChipBaseT<T>::resampledGenerate(int32_t *output) +{ + int32_t samplecnt = m_samplecnt; + const int32_t rateratio = m_rateratio; + while(samplecnt >= rateratio) + { + m_oldsamples[0] = m_samples[0]; + m_oldsamples[1] = m_samples[1]; + int16_t buffer[2]; + static_cast<T *>(this)->nativeGenerate(buffer); + m_samples[0] = buffer[0] * T::resamplerPreAmplify; + m_samples[1] = buffer[1] * T::resamplerPreAmplify; + samplecnt -= rateratio; + } + output[0] = (int32_t)(((m_oldsamples[0] * (rateratio - samplecnt) + + m_samples[0] * samplecnt) / rateratio)/T::resamplerPostAttenuate); + output[1] = (int32_t)(((m_oldsamples[1] * (rateratio - samplecnt) + + m_samples[1] * samplecnt) / rateratio)/T::resamplerPostAttenuate); + m_samplecnt = samplecnt + (1 << rsm_frac); +} +#endif + +/* OPLChipBaseBufferedT */ + +template <class T, unsigned Buffer> +void OPLChipBaseBufferedT<T, Buffer>::reset() +{ + OPLChipBaseT<T>::reset(); + m_bufferIndex = 0; +} + +template <class T, unsigned Buffer> +void OPLChipBaseBufferedT<T, Buffer>::nativeGenerate(int16_t *frame) +{ + unsigned bufferIndex = m_bufferIndex; + if(bufferIndex == 0) + static_cast<T *>(this)->nativeGenerateN(m_buffer, Buffer); + frame[0] = m_buffer[2 * bufferIndex]; + frame[1] = m_buffer[2 * bufferIndex + 1]; + bufferIndex = (bufferIndex + 1 < Buffer) ? (bufferIndex + 1) : 0; + m_bufferIndex = bufferIndex; +} diff --git a/src/fraction.hpp b/src/fraction.hpp index 1ec10ab..1c0a38d 100644 --- a/src/fraction.hpp +++ b/src/fraction.hpp @@ -4,6 +4,7 @@ #include <cmath> #include <limits> + /* Fraction number handling. * Copyright (C) 1992,2001 Bisqwit (http://iki.fi/bisqwit/) */ @@ -82,6 +83,10 @@ public: self &operator= (long double orig); }; +#ifdef _MSC_VER +#pragma warning(disable:4146) +#endif + template<typename inttype> void fraction<inttype>::Optim() { @@ -110,6 +115,10 @@ void fraction<inttype>::Optim() //fprintf(stderr, "result: %d/%d\n\n", nom(), denom()); } +#ifdef _MSC_VER +#pragma warning(default:4146) +#endif + template<typename inttype> inline const fraction<inttype> abs(const fraction<inttype> &f) { diff --git a/src/wopl/wopl_file.h b/src/wopl/wopl_file.h index f5d816b..0e38842 100644 --- a/src/wopl/wopl_file.h +++ b/src/wopl/wopl_file.h @@ -32,6 +32,14 @@ extern "C" { #endif +#if !defined(__STDC_VERSION__) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) \ + || defined(__STRICT_ANSI__) || !defined(__cplusplus) +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int int16_t; +typedef unsigned short int uint16_t; +#endif + /* Global OPL flags */ typedef enum WOPLFileFlags { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..bb5615e --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,7 @@ + +set(CMAKE_CXX_STANDARD 11) + +add_subdirectory(bankmap) + +add_library(Catch-objects OBJECT "common/catch_main.cpp") +target_include_directories(Catch-objects PRIVATE "common") diff --git a/test/bankmap/CMakeLists.txt b/test/bankmap/CMakeLists.txt new file mode 100644 index 0000000..2741637 --- /dev/null +++ b/test/bankmap/CMakeLists.txt @@ -0,0 +1,12 @@ + +set(CMAKE_CXX_STANDARD 11) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../common + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src) + +add_executable(BankMapTest bank_map.cpp $<TARGET_OBJECTS:Catch-objects>) + +set_target_properties(BankMapTest PROPERTIES COMPILE_DEFINITIONS "GSL_THROW_ON_CONTRACT_VIOLATION") +add_test(NAME BankMapTest COMMAND BankMapTest) diff --git a/test/bankmap/bank_map.cpp b/test/bankmap/bank_map.cpp new file mode 100644 index 0000000..613fc59 --- /dev/null +++ b/test/bankmap/bank_map.cpp @@ -0,0 +1,100 @@ +#include <catch.hpp> +#include <random> +#include "adlmidi_bankmap.h" + +typedef BasicBankMap<int> BankMap; +typedef BankMap::value_type ValuePair; +typedef BankMap::iterator Iterator; +typedef std::pair<Iterator, bool> InsertResult; + +static std::mt19937 rng; + +static size_t iterated_size(const BankMap &map) +{ + size_t size = 0; + auto it = map.begin(), end = map.end(); + while(it != end) { + ++it; + ++size; + } + return size; +} + +static bool consistent_size(const BankMap &map) +{ + return map.size() == iterated_size(map); +} + +TEST_CASE("[BankMap] Construction") +{ + BankMap map; + + REQUIRE(map.capacity() == 0); + REQUIRE(map.size() == 0); + REQUIRE(iterated_size(map) == 0); +} + +TEST_CASE("[BankMap] Insert, erase and find") +{ + BankMap map; + + for(unsigned i = 0; i < 10; ++i) { + const uint16_t key = rng(); + const int value = rng(); + + uint16_t another_key = rng(); + while (another_key == key) + another_key = rng(); + + InsertResult ir = map.insert(ValuePair{key, value}); + REQUIRE(ir.second); + REQUIRE(map.size() == 1); + REQUIRE(iterated_size(map) == 1); + + Iterator it = map.find(key); + REQUIRE(it != map.end()); + REQUIRE(it->first == key); + REQUIRE(it->second == value); + REQUIRE(map.find(another_key) == map.end()); + + map.erase(it); + REQUIRE(map.find(key) == map.end()); + REQUIRE(map.size() == 0); + REQUIRE(iterated_size(map) == 0); + } +} + +TEST_CASE("[BankMap] Insert without expanding") +{ + BankMap map; + + InsertResult ir; + ir = map.insert(ValuePair{0, 0}, BankMap::do_not_expand_t()); + REQUIRE(ir.first == map.end()); + REQUIRE(!ir.second); + + map.reserve(1); + REQUIRE(map.capacity() > 1); + + while(map.size() < map.capacity()) { + const uint16_t key = rng(); + const int value = rng(); + if(map.find(key) != map.end()) + continue; + ir = map.insert(ValuePair{key, value}, BankMap::do_not_expand_t()); + REQUIRE(ir.first != map.end()); + REQUIRE(ir.first->first == key); + REQUIRE(ir.first->second == value); + REQUIRE(ir.second); + REQUIRE(consistent_size(map)); + } + + ir = map.insert(ValuePair{0, 0}, BankMap::do_not_expand_t()); + REQUIRE(ir.first == map.end()); + REQUIRE(!ir.second); + REQUIRE(consistent_size(map)); + + map.clear(); + REQUIRE(map.size() == 0); + REQUIRE(consistent_size(map)); +} diff --git a/test/common/catch.hpp b/test/common/catch.hpp new file mode 100644 index 0000000..ecd8907 --- /dev/null +++ b/test/common/catch.hpp @@ -0,0 +1,13050 @@ +/* + * Catch v2.2.2 + * Generated: 2018-04-06 12:05:03.186665 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 2 +#define CATCH_VERSION_PATCH 2 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic ignored "-Wunused-variable" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic ignored "-Wparentheses" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +#ifdef __APPLE__ +# include <TargetConditionals.h> +# if TARGET_OS_OSX == 1 +# define CATCH_PLATFORM_MAC +# elif TARGET_OS_IPHONE == 1 +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_<feature name> form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if __cplusplus >= 201402L +# define CATCH_CPP14_OR_GREATER +# endif + +# if __cplusplus >= 201703L +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +#if defined(CATCH_CPP17_OR_GREATER) +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#ifdef __clang__ + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") +# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic pop" ) + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic pop" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE + +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +# if _MSC_VER >= 1900 // Visual Studio 2015 or newer +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +# endif + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include <iosfwd> +#include <string> +#include <cstdint> + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo( SourceLineInfo && ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo& operator = ( SourceLineInfo && ) = default; + + bool empty() const noexcept; + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template<typename T> + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include <vector> +#include <memory> + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + using ITestCasePtr = std::shared_ptr<ITestInvoker>; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector<TestCase> const& getAllTests() const = 0; + virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include <cstddef> +#include <string> +#include <iosfwd> + +namespace Catch { + + class StringData; + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. c_str() must return a null terminated + /// string, however, and so the StringRef will internally take ownership + /// (taking a copy), if necessary. In theory this ownership is not externally + /// visible - but it does mean (substring) StringRefs should not be shared between + /// threads. + class StringRef { + public: + using size_type = std::size_t; + + private: + friend struct StringRefTestAccess; + + char const* m_start; + size_type m_size; + + char* m_data = nullptr; + + void takeOwnership(); + + static constexpr char const* const s_empty = ""; + + public: // construction/ assignment + StringRef() noexcept + : StringRef( s_empty, 0 ) + {} + + StringRef( StringRef const& other ) noexcept + : m_start( other.m_start ), + m_size( other.m_size ) + {} + + StringRef( StringRef&& other ) noexcept + : m_start( other.m_start ), + m_size( other.m_size ), + m_data( other.m_data ) + { + other.m_data = nullptr; + } + + StringRef( char const* rawChars ) noexcept; + + StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + ~StringRef() noexcept { + delete[] m_data; + } + + auto operator = ( StringRef const &other ) noexcept -> StringRef& { + delete[] m_data; + m_data = nullptr; + m_start = other.m_start; + m_size = other.m_size; + return *this; + } + + operator std::string() const; + + void swap( StringRef& other ) noexcept; + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != ( StringRef const& other ) const noexcept -> bool; + + auto operator[] ( size_type index ) const noexcept -> char; + + public: // named queries + auto empty() const noexcept -> bool { + return m_size == 0; + } + auto size() const noexcept -> size_type { + return m_size; + } + + auto numberOfCharacters() const noexcept -> size_type; + auto c_str() const -> char const*; + + public: // substrings and searches + auto substr( size_type start, size_type size ) const noexcept -> StringRef; + + // Returns the current start pointer. + // Note that the pointer can change when if the StringRef is a substring + auto currentData() const noexcept -> char const*; + + private: // ownership queries - may not be consistent between calls + auto isOwned() const noexcept -> bool; + auto isSubstring() const noexcept -> bool; + }; + + auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; + auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; + auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } + +} // namespace Catch + +// end catch_stringref.h +namespace Catch { + +template<typename C> +class TestInvokerAsMethod : public ITestInvoker { + void (C::*m_testAsMethod)(); +public: + TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {} + + void invoke() const override { + C obj; + (obj.*m_testAsMethod)(); + } +}; + +auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*; + +template<typename C> +auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* { + return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod ); +} + +struct NameAndTags { + NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept; + StringRef name; + StringRef tags; +}; + +struct AutoReg : NonCopyable { + AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept; + ~AutoReg(); +}; + +} // end namespace Catch + +#if defined(CATCH_CONFIG_DISABLE) + #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ + namespace{ \ + struct TestName : ClassName { \ + void test(); \ + }; \ + } \ + void TestName::test() + +#endif + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ \ + struct TestName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +// end catch_test_registry.h +// start catch_capture.hpp + +// start catch_assertionhandler.h + +// start catch_assertioninfo.h + +// start catch_result_type.h + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + bool isOk( ResultWas::OfType resultType ); + bool isJustInfo( int flags ); + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ); + + bool shouldContinueOnFailure( int flags ); + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + bool shouldSuppressFailure( int flags ); + +} // end namespace Catch + +// end catch_result_type.h +namespace Catch { + + struct AssertionInfo + { + StringRef macroName; + SourceLineInfo lineInfo; + StringRef capturedExpression; + ResultDisposition::Flags resultDisposition; + + // We want to delete this constructor but a compiler bug in 4.8 means + // the struct is then treated as non-aggregate + //AssertionInfo() = delete; + }; + +} // end namespace Catch + +// end catch_assertioninfo.h +// start catch_decomposer.h + +// start catch_tostring.h + +#include <vector> +#include <cstddef> +#include <type_traits> +#include <string> +// start catch_stream.h + +#include <iosfwd> +#include <cstddef> +#include <ostream> + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + std::ostream& clog(); + + class StringRef; + + struct IStream { + virtual ~IStream(); + virtual std::ostream& stream() const = 0; + }; + + auto makeStream( StringRef const &filename ) -> IStream const*; + + class ReusableStringStream { + std::size_t m_index; + std::ostream* m_oss; + public: + ReusableStringStream(); + ~ReusableStringStream(); + + auto str() const -> std::string; + + template<typename T> + auto operator << ( T const& value ) -> ReusableStringStream& { + *m_oss << value; + return *this; + } + auto get() -> std::ostream& { return *m_oss; } + + static void cleanup(); + }; +} + +// end catch_stream.h + +#ifdef __OBJC__ +// start catch_objc_arc.hpp + +#import <Foundation/Foundation.h> + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +// end catch_objc_arc.hpp +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless +#endif + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + // Bring in operator<< from global namespace into Catch namespace + using ::operator<<; + + namespace Detail { + + extern const std::string unprintableString; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template<typename T> + std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + + template<typename T> + class IsStreamInsertable { + template<typename SS, typename TT> + static auto test(int) + -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type()); + + template<typename, typename> + static auto test(...)->std::false_type; + + public: + static const bool value = decltype(test<std::ostream, const T&>(0))::value; + }; + + template<typename E> + std::string convertUnknownEnumToString( E e ); + + template<typename T> + typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) { +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) + (void)value; + return Detail::unprintableString; +#else + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); +#endif + } + template<typename T> + typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) { + return convertUnknownEnumToString( value ); + } + +#if defined(_MANAGED) + //! Convert a CLR string to a utf8 std::string + template<typename T> + std::string clrReferenceToString( T^ ref ) { + if (ref == nullptr) + return std::string("null"); + auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString()); + cli::pin_ptr<System::Byte> p = &bytes[0]; + return std::string(reinterpret_cast<char const *>(p), bytes->Length); + } +#endif + + } // namespace Detail + + // If we decide for C++14, change these to enable_if_ts + template <typename T, typename = void> + struct StringMaker { + template <typename Fake = T> + static + typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type + convert(const Fake& value) { + ReusableStringStream rss; + rss << value; + return rss.str(); + } + + template <typename Fake = T> + static + typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type + convert( const Fake& value ) { + return Detail::convertUnstreamable( value ); + } + }; + + namespace Detail { + + // This function dispatches all stringification requests inside of Catch. + // Should be preferably called fully qualified, like ::Catch::Detail::stringify + template <typename T> + std::string stringify(const T& e) { + return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e); + } + + template<typename E> + std::string convertUnknownEnumToString( E e ) { + return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e)); + } + +#if defined(_MANAGED) + template <typename T> + std::string stringify( T^ e ) { + return ::Catch::StringMaker<T^>::convert(e); + } +#endif + + } // namespace Detail + + // Some predefined specializations + + template<> + struct StringMaker<std::string> { + static std::string convert(const std::string& str); + }; +#ifdef CATCH_CONFIG_WCHAR + template<> + struct StringMaker<std::wstring> { + static std::string convert(const std::wstring& wstr); + }; +#endif + + template<> + struct StringMaker<char const *> { + static std::string convert(char const * str); + }; + template<> + struct StringMaker<char *> { + static std::string convert(char * str); + }; + +#ifdef CATCH_CONFIG_WCHAR + template<> + struct StringMaker<wchar_t const *> { + static std::string convert(wchar_t const * str); + }; + template<> + struct StringMaker<wchar_t *> { + static std::string convert(wchar_t * str); + }; +#endif + + // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer, + // while keeping string semantics? + template<int SZ> + struct StringMaker<char[SZ]> { + static std::string convert(char const* str) { + return ::Catch::Detail::stringify(std::string{ str }); + } + }; + template<int SZ> + struct StringMaker<signed char[SZ]> { + static std::string convert(signed char const* str) { + return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) }); + } + }; + template<int SZ> + struct StringMaker<unsigned char[SZ]> { + static std::string convert(unsigned char const* str) { + return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) }); + } + }; + + template<> + struct StringMaker<int> { + static std::string convert(int value); + }; + template<> + struct StringMaker<long> { + static std::string convert(long value); + }; + template<> + struct StringMaker<long long> { + static std::string convert(long long value); + }; + template<> + struct StringMaker<unsigned int> { + static std::string convert(unsigned int value); + }; + template<> + struct StringMaker<unsigned long> { + static std::string convert(unsigned long value); + }; + template<> + struct StringMaker<unsigned long long> { + static std::string convert(unsigned long long value); + }; + + template<> + struct StringMaker<bool> { + static std::string convert(bool b); + }; + + template<> + struct StringMaker<char> { + static std::string convert(char c); + }; + template<> + struct StringMaker<signed char> { + static std::string convert(signed char c); + }; + template<> + struct StringMaker<unsigned char> { + static std::string convert(unsigned char c); + }; + + template<> + struct StringMaker<std::nullptr_t> { + static std::string convert(std::nullptr_t); + }; + + template<> + struct StringMaker<float> { + static std::string convert(float value); + }; + template<> + struct StringMaker<double> { + static std::string convert(double value); + }; + + template <typename T> + struct StringMaker<T*> { + template <typename U> + static std::string convert(U* p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } + }; + + template <typename R, typename C> + struct StringMaker<R C::*> { + static std::string convert(R C::* p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } + }; + +#if defined(_MANAGED) + template <typename T> + struct StringMaker<T^> { + static std::string convert( T^ ref ) { + return ::Catch::Detail::clrReferenceToString(ref); + } + }; +#endif + + namespace Detail { + template<typename InputIterator> + std::string rangeToString(InputIterator first, InputIterator last) { + ReusableStringStream rss; + rss << "{ "; + if (first != last) { + rss << ::Catch::Detail::stringify(*first); + for (++first; first != last; ++first) + rss << ", " << ::Catch::Detail::stringify(*first); + } + rss << " }"; + return rss.str(); + } + } + +#ifdef __OBJC__ + template<> + struct StringMaker<NSString*> { + static std::string convert(NSString * nsstring) { + if (!nsstring) + return "nil"; + return std::string("@") + [nsstring UTF8String]; + } + }; + template<> + struct StringMaker<NSObject*> { + static std::string convert(NSObject* nsObject) { + return ::Catch::Detail::stringify([nsObject description]); + } + + }; + namespace Detail { + inline std::string stringify( NSString* nsstring ) { + return StringMaker<NSString*>::convert( nsstring ); + } + + } // namespace Detail +#endif // __OBJC__ + +} // namespace Catch + +////////////////////////////////////////////////////// +// Separate std-lib types stringification, so it can be selectively enabled +// This means that we do not bring in + +#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) +# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER +# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +// Separate std::pair specialization +#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER) +#include <utility> +namespace Catch { + template<typename T1, typename T2> + struct StringMaker<std::pair<T1, T2> > { + static std::string convert(const std::pair<T1, T2>& pair) { + ReusableStringStream rss; + rss << "{ " + << ::Catch::Detail::stringify(pair.first) + << ", " + << ::Catch::Detail::stringify(pair.second) + << " }"; + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER + +// Separate std::tuple specialization +#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER) +#include <tuple> +namespace Catch { + namespace Detail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size<Tuple>::value) + > + struct TupleElementPrinter { + static void print(const Tuple& tuple, std::ostream& os) { + os << (N ? ", " : " ") + << ::Catch::Detail::stringify(std::get<N>(tuple)); + TupleElementPrinter<Tuple, N + 1>::print(tuple, os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct TupleElementPrinter<Tuple, N, false> { + static void print(const Tuple&, std::ostream&) {} + }; + + } + + template<typename ...Types> + struct StringMaker<std::tuple<Types...>> { + static std::string convert(const std::tuple<Types...>& tuple) { + ReusableStringStream rss; + rss << '{'; + Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get()); + rss << " }"; + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER + +namespace Catch { + struct not_this_one {}; // Tag type for detecting which begin/ end are being selected + + // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace + using std::begin; + using std::end; + + not_this_one begin( ... ); + not_this_one end( ... ); + + template <typename T> + struct is_range { + static const bool value = + !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value && + !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value; + }; + +#if defined(_MANAGED) // Managed types are never ranges + template <typename T> + struct is_range<T^> { + static const bool value = false; + }; +#endif + + template<typename Range> + std::string rangeToString( Range const& range ) { + return ::Catch::Detail::rangeToString( begin( range ), end( range ) ); + } + + // Handle vector<bool> specially + template<typename Allocator> + std::string rangeToString( std::vector<bool, Allocator> const& v ) { + ReusableStringStream rss; + rss << "{ "; + bool first = true; + for( bool b : v ) { + if( first ) + first = false; + else + rss << ", "; + rss << ::Catch::Detail::stringify( b ); + } + rss << " }"; + return rss.str(); + } + + template<typename R> + struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> { + static std::string convert( R const& range ) { + return rangeToString( range ); + } + }; + + template <typename T, int SZ> + struct StringMaker<T[SZ]> { + static std::string convert(T const(&arr)[SZ]) { + return rangeToString(arr); + } + }; + +} // namespace Catch + +// Separate std::chrono::duration specialization +#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#include <ctime> +#include <ratio> +#include <chrono> + +namespace Catch { + +template <class Ratio> +struct ratio_string { + static std::string symbol(); +}; + +template <class Ratio> +std::string ratio_string<Ratio>::symbol() { + Catch::ReusableStringStream rss; + rss << '[' << Ratio::num << '/' + << Ratio::den << ']'; + return rss.str(); +} +template <> +struct ratio_string<std::atto> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::femto> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::pico> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::nano> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::micro> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::milli> { + static std::string symbol(); +}; + + //////////// + // std::chrono::duration specializations + template<typename Value, typename Ratio> + struct StringMaker<std::chrono::duration<Value, Ratio>> { + static std::string convert(std::chrono::duration<Value, Ratio> const& duration) { + ReusableStringStream rss; + rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's'; + return rss.str(); + } + }; + template<typename Value> + struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> { + static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " s"; + return rss.str(); + } + }; + template<typename Value> + struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> { + static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " m"; + return rss.str(); + } + }; + template<typename Value> + struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> { + static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " h"; + return rss.str(); + } + }; + + //////////// + // std::chrono::time_point specialization + // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock> + template<typename Clock, typename Duration> + struct StringMaker<std::chrono::time_point<Clock, Duration>> { + static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) { + return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch"; + } + }; + // std::chrono::time_point<system_clock> specialization + template<typename Duration> + struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> { + static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) { + auto converted = std::chrono::system_clock::to_time_t(time_point); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &converted); +#else + std::tm* timeInfo = std::gmtime(&converted); +#endif + + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_tostring.h +#include <iosfwd> + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#pragma warning(disable:4018) // more "signed/unsigned mismatch" +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#pragma warning(disable:4180) // qualifier applied to function type has no meaning +#endif + +namespace Catch { + + struct ITransientExpression { + auto isBinaryExpression() const -> bool { return m_isBinaryExpression; } + auto getResult() const -> bool { return m_result; } + virtual void streamReconstructedExpression( std::ostream &os ) const = 0; + + ITransientExpression( bool isBinaryExpression, bool result ) + : m_isBinaryExpression( isBinaryExpression ), + m_result( result ) + {} + + // We don't actually need a virtual destructor, but many static analysers + // complain if it's not here :-( + virtual ~ITransientExpression(); + + bool m_isBinaryExpression; + bool m_result; + + }; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ); + + template<typename LhsT, typename RhsT> + class BinaryExpr : public ITransientExpression { + LhsT m_lhs; + StringRef m_op; + RhsT m_rhs; + + void streamReconstructedExpression( std::ostream &os ) const override { + formatReconstructedExpression + ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) ); + } + + public: + BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs ) + : ITransientExpression{ true, comparisonResult }, + m_lhs( lhs ), + m_op( op ), + m_rhs( rhs ) + {} + }; + + template<typename LhsT> + class UnaryExpr : public ITransientExpression { + LhsT m_lhs; + + void streamReconstructedExpression( std::ostream &os ) const override { + os << Catch::Detail::stringify( m_lhs ); + } + + public: + explicit UnaryExpr( LhsT lhs ) + : ITransientExpression{ false, lhs ? true : false }, + m_lhs( lhs ) + {} + }; + + // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int) + template<typename LhsT, typename RhsT> + auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); } + template<typename T> + auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } + template<typename T> + auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } + + template<typename LhsT, typename RhsT> + auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); } + template<typename T> + auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } + template<typename T> + auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } + + template<typename LhsT> + class ExprLhs { + LhsT m_lhs; + public: + explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {} + + template<typename RhsT> + auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs }; + } + auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const { + return { m_lhs == rhs, m_lhs, "==", rhs }; + } + + template<typename RhsT> + auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs }; + } + auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const { + return { m_lhs != rhs, m_lhs, "!=", rhs }; + } + + template<typename RhsT> + auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs }; + } + template<typename RhsT> + auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs }; + } + template<typename RhsT> + auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs }; + } + template<typename RhsT> + auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs }; + } + + auto makeUnaryExpr() const -> UnaryExpr<LhsT> { + return UnaryExpr<LhsT>{ m_lhs }; + } + }; + + void handleExpression( ITransientExpression const& expr ); + + template<typename T> + void handleExpression( ExprLhs<T> const& expr ) { + handleExpression( expr.makeUnaryExpr() ); + } + + struct Decomposer { + template<typename T> + auto operator <= ( T const& lhs ) -> ExprLhs<T const&> { + return ExprLhs<T const&>{ lhs }; + } + + auto operator <=( bool value ) -> ExprLhs<bool> { + return ExprLhs<bool>{ value }; + } + }; + +} // end namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_decomposer.h +// start catch_interfaces_capture.h + +#include <string> + +namespace Catch { + + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + struct Counts; + struct BenchmarkInfo; + struct BenchmarkStats; + struct AssertionReaction; + + struct ITransientExpression; + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + + virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; + virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0; + + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual void handleFatalErrorCondition( StringRef message ) = 0; + + virtual void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) = 0; + virtual void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction ) = 0; + virtual void handleIncomplete + ( AssertionInfo const& info ) = 0; + virtual void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + + // Deprecated, do not use: + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + virtual void exceptionEarlyReported() = 0; + }; + + IResultCapture& getResultCapture(); +} + +// end catch_interfaces_capture.h +namespace Catch { + + struct TestFailureException{}; + struct AssertionResultData; + struct IResultCapture; + class RunContext; + + class LazyExpression { + friend class AssertionHandler; + friend struct AssertionStats; + friend class RunContext; + + ITransientExpression const* m_transientExpression = nullptr; + bool m_isNegated; + public: + LazyExpression( bool isNegated ); + LazyExpression( LazyExpression const& other ); + LazyExpression& operator = ( LazyExpression const& ) = delete; + + explicit operator bool() const; + + friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&; + }; + + struct AssertionReaction { + bool shouldDebugBreak = false; + bool shouldThrow = false; + }; + + class AssertionHandler { + AssertionInfo m_assertionInfo; + AssertionReaction m_reaction; + bool m_completed = false; + IResultCapture& m_resultCapture; + + public: + AssertionHandler + ( StringRef macroName, + SourceLineInfo const& lineInfo, + StringRef capturedExpression, + ResultDisposition::Flags resultDisposition ); + ~AssertionHandler() { + if ( !m_completed ) { + m_resultCapture.handleIncomplete( m_assertionInfo ); + } + } + + template<typename T> + void handleExpr( ExprLhs<T> const& expr ) { + handleExpr( expr.makeUnaryExpr() ); + } + void handleExpr( ITransientExpression const& expr ); + + void handleMessage(ResultWas::OfType resultType, StringRef const& message); + + void handleExceptionThrownAsExpected(); + void handleUnexpectedExceptionNotThrown(); + void handleExceptionNotThrownAsExpected(); + void handleThrowingCallSkipped(); + void handleUnexpectedInflightException(); + + void complete(); + void setCompleted(); + + // query + auto allowThrows() const -> bool; + }; + + void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ); + +} // namespace Catch + +// end catch_assertionhandler.h +// start catch_message.h + +#include <string> + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + std::string message; + SourceLineInfo lineInfo; + ResultWas::OfType type; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const; + bool operator < ( MessageInfo const& other ) const; + private: + static unsigned int globalCount; + }; + + struct MessageStream { + + template<typename T> + MessageStream& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + ReusableStringStream m_stream; + }; + + struct MessageBuilder : MessageStream { + MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ); + + template<typename T> + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + }; + + class ScopedMessage { + public: + explicit ScopedMessage( MessageBuilder const& builder ); + ~ScopedMessage(); + + MessageInfo m_info; + }; + +} // end namespace Catch + +// end catch_message.h +#if !defined(CATCH_CONFIG_DISABLE) + +#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) + #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ +#else + #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" +#endif + +#if defined(CATCH_CONFIG_FAST_COMPILE) + +/////////////////////////////////////////////////////////////////////////////// +// Another way to speed-up compilation is to omit local try-catch for REQUIRE* +// macros. +#define INTERNAL_CATCH_TRY +#define INTERNAL_CATCH_CATCH( capturer ) + +#else // CATCH_CONFIG_FAST_COMPILE + +#define INTERNAL_CATCH_TRY try +#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); } + +#endif + +#define INTERNAL_CATCH_REACT( handler ) handler.complete(); + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ + INTERNAL_CATCH_TRY { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look + // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ + if( Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ + if( !Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ + try { \ + static_cast<void>(__VA_ARGS__); \ + catchAssertionHandler.handleExceptionNotThrownAsExpected(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(expr); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( exceptionType const& ) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( macroName, log ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); + +/////////////////////////////////////////////////////////////////////////////// +// Although this is matcher-based, it can be used with just a string +#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( ... ) { \ + Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_capture.hpp +// start catch_section.h + +// start catch_section_info.h + +// start catch_totals.h + +#include <cstddef> + +namespace Catch { + + struct Counts { + Counts operator - ( Counts const& other ) const; + Counts& operator += ( Counts const& other ); + + std::size_t total() const; + bool allPassed() const; + bool allOk() const; + + std::size_t passed = 0; + std::size_t failed = 0; + std::size_t failedButOk = 0; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const; + Totals& operator += ( Totals const& other ); + + Totals delta( Totals const& prevTotals ) const; + + int error = 0; + Counts assertions; + Counts testCases; + }; +} + +// end catch_totals.h +#include <string> + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description = std::string() ); + + std::string name; + std::string description; + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ); + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +// end catch_section_info.h +// start catch_timer.h + +#include <cstdint> + +namespace Catch { + + auto getCurrentNanosecondsSinceEpoch() -> uint64_t; + auto getEstimatedClockResolution() -> uint64_t; + + class Timer { + uint64_t m_nanoseconds = 0; + public: + void start(); + auto getElapsedNanoseconds() const -> uint64_t; + auto getElapsedMicroseconds() const -> uint64_t; + auto getElapsedMilliseconds() const -> unsigned int; + auto getElapsedSeconds() const -> double; + }; + +} // namespace Catch + +// end catch_timer.h +#include <string> + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + explicit operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + + #define INTERNAL_CATCH_SECTION( ... ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) + +// end catch_section.h +// start catch_benchmark.h + +#include <cstdint> +#include <string> + +namespace Catch { + + class BenchmarkLooper { + + std::string m_name; + std::size_t m_count = 0; + std::size_t m_iterationsToRun = 1; + uint64_t m_resolution; + Timer m_timer; + + static auto getResolution() -> uint64_t; + public: + // Keep most of this inline as it's on the code path that is being timed + BenchmarkLooper( StringRef name ) + : m_name( name ), + m_resolution( getResolution() ) + { + reportStart(); + m_timer.start(); + } + + explicit operator bool() { + if( m_count < m_iterationsToRun ) + return true; + return needsMoreIterations(); + } + + void increment() { + ++m_count; + } + + void reportStart(); + auto needsMoreIterations() -> bool; + }; + +} // end namespace Catch + +#define BENCHMARK( name ) \ + for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() ) + +// end catch_benchmark.h +// start catch_interfaces_exception.h + +// start catch_interfaces_registry_hub.h + +#include <string> +#include <memory> + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + struct ITagAliasRegistry; + class StartupExceptionRegistry; + + using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; + + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; + + virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0; + virtual void registerListener( IReporterFactoryPtr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; + virtual void registerStartupException() noexcept = 0; + }; + + IRegistryHub& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +// end catch_interfaces_registry_hub.h +#if defined(CATCH_CONFIG_DISABLE) + #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ + static std::string translatorName( signature ) +#endif + +#include <exception> +#include <string> +#include <vector> + +namespace Catch { + using exceptionTranslateFunction = std::string(*)(); + + struct IExceptionTranslator; + using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template<typename T> + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { + try { + if( it == itEnd ) + std::rethrow_exception(std::current_exception()); + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template<typename T> + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator<T>( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// end catch_interfaces_exception.h +// start catch_approx.h + +#include <type_traits> +#include <stdexcept> + +namespace Catch { +namespace Detail { + + class Approx { + private: + bool equalityComparisonImpl(double other) const; + + public: + explicit Approx ( double value ); + + static Approx custom(); + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx operator()( T const& value ) { + Approx approx( static_cast<double>(value) ); + approx.epsilon( m_epsilon ); + approx.margin( m_margin ); + approx.scale( m_scale ); + return approx; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + explicit Approx( T const& value ): Approx(static_cast<double>(value)) + {} + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator == ( const T& lhs, Approx const& rhs ) { + auto lhs_v = static_cast<double>(lhs); + return rhs.equalityComparisonImpl(lhs_v); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator == ( Approx const& lhs, const T& rhs ) { + return operator==( rhs, lhs ); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator != ( T const& lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator != ( Approx const& lhs, T const& rhs ) { + return !operator==( rhs, lhs ); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator <= ( T const& lhs, Approx const& rhs ) { + return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator <= ( Approx const& lhs, T const& rhs ) { + return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator >= ( T const& lhs, Approx const& rhs ) { + return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator >= ( Approx const& lhs, T const& rhs ) { + return lhs.m_value > static_cast<double>(rhs) || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx& epsilon( T const& newEpsilon ) { + double epsilonAsDouble = static_cast<double>(newEpsilon); + if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) { + throw std::domain_error + ( "Invalid Approx::epsilon: " + + Catch::Detail::stringify( epsilonAsDouble ) + + ", Approx::epsilon has to be between 0 and 1" ); + } + m_epsilon = epsilonAsDouble; + return *this; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx& margin( T const& newMargin ) { + double marginAsDouble = static_cast<double>(newMargin); + if( marginAsDouble < 0 ) { + throw std::domain_error + ( "Invalid Approx::margin: " + + Catch::Detail::stringify( marginAsDouble ) + + ", Approx::Margin has to be non-negative." ); + + } + m_margin = marginAsDouble; + return *this; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx& scale( T const& newScale ) { + m_scale = static_cast<double>(newScale); + return *this; + } + + std::string toString() const; + + private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; + }; +} + +template<> +struct StringMaker<Catch::Detail::Approx> { + static std::string convert(Catch::Detail::Approx const& value); +}; + +} // end namespace Catch + +// end catch_approx.h +// start catch_string_manip.h + +#include <string> +#include <iosfwd> + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + std::string trim( std::string const& str ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; +} + +// end catch_string_manip.h +#ifndef CATCH_CONFIG_DISABLE_MATCHERS +// start catch_capture_matchers.h + +// start catch_matchers.h + +#include <string> +#include <vector> + +namespace Catch { +namespace Matchers { + namespace Impl { + + template<typename ArgT> struct MatchAllOf; + template<typename ArgT> struct MatchAnyOf; + template<typename ArgT> struct MatchNotOf; + + class MatcherUntypedBase { + public: + MatcherUntypedBase() = default; + MatcherUntypedBase ( MatcherUntypedBase const& ) = default; + MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete; + std::string toString() const; + + protected: + virtual ~MatcherUntypedBase(); + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; + }; + + template<typename ObjectT> + struct MatcherMethod { + virtual bool match( ObjectT const& arg ) const = 0; + }; + template<typename PtrT> + struct MatcherMethod<PtrT*> { + virtual bool match( PtrT* arg ) const = 0; + }; + + template<typename T> + struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> { + + MatchAllOf<T> operator && ( MatcherBase const& other ) const; + MatchAnyOf<T> operator || ( MatcherBase const& other ) const; + MatchNotOf<T> operator ! () const; + }; + + template<typename ArgT> + struct MatchAllOf : MatcherBase<ArgT> { + bool match( ArgT const& arg ) const override { + for( auto matcher : m_matchers ) { + if (!matcher->match(arg)) + return false; + } + return true; + } + std::string describe() const override { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + bool first = true; + for( auto matcher : m_matchers ) { + if( first ) + first = false; + else + description += " and "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector<MatcherBase<ArgT> const*> m_matchers; + }; + template<typename ArgT> + struct MatchAnyOf : MatcherBase<ArgT> { + + bool match( ArgT const& arg ) const override { + for( auto matcher : m_matchers ) { + if (matcher->match(arg)) + return true; + } + return false; + } + std::string describe() const override { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + bool first = true; + for( auto matcher : m_matchers ) { + if( first ) + first = false; + else + description += " or "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector<MatcherBase<ArgT> const*> m_matchers; + }; + + template<typename ArgT> + struct MatchNotOf : MatcherBase<ArgT> { + + MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} + + bool match( ArgT const& arg ) const override { + return !m_underlyingMatcher.match( arg ); + } + + std::string describe() const override { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase<ArgT> const& m_underlyingMatcher; + }; + + template<typename T> + MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const { + return MatchAllOf<T>() && *this && other; + } + template<typename T> + MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const { + return MatchAnyOf<T>() || *this || other; + } + template<typename T> + MatchNotOf<T> MatcherBase<T>::operator ! () const { + return MatchNotOf<T>( *this ); + } + + } // namespace Impl + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +// end catch_matchers.h +// start catch_matchers_floating.h + +#include <type_traits> +#include <cmath> + +namespace Catch { +namespace Matchers { + + namespace Floating { + + enum class FloatingPointKind : uint8_t; + + struct WithinAbsMatcher : MatcherBase<double> { + WithinAbsMatcher(double target, double margin); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + double m_margin; + }; + + struct WithinUlpsMatcher : MatcherBase<double> { + WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + int m_ulps; + FloatingPointKind m_type; + }; + + } // namespace Floating + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff); + Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff); + Floating::WithinAbsMatcher WithinAbs(double target, double margin); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.h +// start catch_matchers_generic.hpp + +#include <functional> +#include <string> + +namespace Catch { +namespace Matchers { +namespace Generic { + +namespace Detail { + std::string finalizeDescription(const std::string& desc); +} + +template <typename T> +class PredicateMatcher : public MatcherBase<T> { + std::function<bool(T const&)> m_predicate; + std::string m_description; +public: + + PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr) + :m_predicate(std::move(elem)), + m_description(Detail::finalizeDescription(descr)) + {} + + bool match( T const& item ) const override { + return m_predicate(item); + } + + std::string describe() const override { + return m_description; + } +}; + +} // namespace Generic + + // The following functions create the actual matcher objects. + // The user has to explicitly specify type to the function, because + // infering std::function<bool(T const&)> is hard (but possible) and + // requires a lot of TMP. + template<typename T> + Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") { + return Generic::PredicateMatcher<T>(predicate, description); + } + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_generic.hpp +// start catch_matchers_string.h + +#include <string> + +namespace Catch { +namespace Matchers { + + namespace StdString { + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); + std::string adjustString( std::string const& str ) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct StringMatcherBase : MatcherBase<std::string> { + StringMatcherBase( std::string const& operation, CasedString const& comparator ); + std::string describe() const override; + + CasedString m_comparator; + std::string m_operation; + }; + + struct EqualsMatcher : StringMatcherBase { + EqualsMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct ContainsMatcher : StringMatcherBase { + ContainsMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + + struct RegexMatcher : MatcherBase<std::string> { + RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity ); + bool match( std::string const& matchee ) const override; + std::string describe() const override; + + private: + std::string m_regex; + CaseSensitive::Choice m_caseSensitivity; + }; + + } // namespace StdString + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_string.h +// start catch_matchers_vector.h + +#include <algorithm> + +namespace Catch { +namespace Matchers { + + namespace Vector { + namespace Detail { + template <typename InputIterator, typename T> + size_t count(InputIterator first, InputIterator last, T const& item) { + size_t cnt = 0; + for (; first != last; ++first) { + if (*first == item) { + ++cnt; + } + } + return cnt; + } + template <typename InputIterator, typename T> + bool contains(InputIterator first, InputIterator last, T const& item) { + for (; first != last; ++first) { + if (*first == item) { + return true; + } + } + return false; + } + } + + template<typename T> + struct ContainsElementMatcher : MatcherBase<std::vector<T>> { + + ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} + + bool match(std::vector<T> const &v) const override { + for (auto const& el : v) { + if (el == m_comparator) { + return true; + } + } + return false; + } + + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify( m_comparator ); + } + + T const& m_comparator; + }; + + template<typename T> + struct ContainsMatcher : MatcherBase<std::vector<T>> { + + ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector<T> const &v) const override { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (auto const& comparator : m_comparator) { + auto present = false; + for (const auto& el : v) { + if (el == comparator) { + present = true; + break; + } + } + if (!present) { + return false; + } + } + return true; + } + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify( m_comparator ); + } + + std::vector<T> const& m_comparator; + }; + + template<typename T> + struct EqualsMatcher : MatcherBase<std::vector<T>> { + + EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector<T> const &v) const override { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector<T> etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (std::size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + std::string describe() const override { + return "Equals: " + ::Catch::Detail::stringify( m_comparator ); + } + std::vector<T> const& m_comparator; + }; + + template<typename T> + struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> { + UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {} + bool match(std::vector<T> const& vec) const override { + // Note: This is a reimplementation of std::is_permutation, + // because I don't want to include <algorithm> inside the common path + if (m_target.size() != vec.size()) { + return false; + } + auto lfirst = m_target.begin(), llast = m_target.end(); + auto rfirst = vec.begin(), rlast = vec.end(); + // Cut common prefix to optimize checking of permuted parts + while (lfirst != llast && *lfirst != *rfirst) { + ++lfirst; ++rfirst; + } + if (lfirst == llast) { + return true; + } + + for (auto mid = lfirst; mid != llast; ++mid) { + // Skip already counted items + if (Detail::contains(lfirst, mid, *mid)) { + continue; + } + size_t num_vec = Detail::count(rfirst, rlast, *mid); + if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) { + return false; + } + } + + return true; + } + + std::string describe() const override { + return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); + } + private: + std::vector<T> const& m_target; + }; + + } // namespace Vector + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + template<typename T> + Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) { + return Vector::ContainsMatcher<T>( comparator ); + } + + template<typename T> + Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher<T>( comparator ); + } + + template<typename T> + Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) { + return Vector::EqualsMatcher<T>( comparator ); + } + + template<typename T> + Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) { + return Vector::UnorderedEqualsMatcher<T>(target); + } + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_vector.h +namespace Catch { + + template<typename ArgT, typename MatcherT> + class MatchExpr : public ITransientExpression { + ArgT const& m_arg; + MatcherT m_matcher; + StringRef m_matcherString; + public: + MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) + : ITransientExpression{ true, matcher.match( arg ) }, + m_arg( arg ), + m_matcher( matcher ), + m_matcherString( matcherString ) + {} + + void streamReconstructedExpression( std::ostream &os ) const override { + auto matcherAsString = m_matcher.toString(); + os << Catch::Detail::stringify( m_arg ) << ' '; + if( matcherAsString == Detail::unprintableString ) + os << m_matcherString; + else + os << matcherAsString; + } + }; + + using StringMatcher = Matchers::Impl::MatcherBase<std::string>; + + void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ); + + template<typename ArgT, typename MatcherT> + auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr<ArgT, MatcherT> { + return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString ); + } + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + INTERNAL_CATCH_TRY { \ + catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \ + } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(__VA_ARGS__ ); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( exceptionType const& ex ) { \ + catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +// end catch_capture_matchers.h +#endif + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// start catch_test_case_info.h + +#include <string> +#include <vector> +#include <memory> + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestInvoker; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5, + Benchmark = 1 << 6 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::vector<std::string> const& _tags, + SourceLineInfo const& _lineInfo ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string tagsAsString() const; + + std::string name; + std::string className; + std::string description; + std::vector<std::string> tags; + std::vector<std::string> lcaseTags; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestInvoker* testCase, TestCaseInfo&& info ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + + private: + std::shared_ptr<ITestInvoker> test; + }; + + TestCase makeTestCase( ITestInvoker* testCase, + std::string const& className, + NameAndTags const& nameAndTags, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_case_info.h +// start catch_interfaces_runner.h + +namespace Catch { + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +// end catch_interfaces_runner.h + +#ifdef __OBJC__ +// start catch_objc.hpp + +#import <objc/runtime.h> + +#include <string> + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public ITestInvoker { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline std::size_t registerTestMethods() { + std::size_t noTestMethods = 0; + int noClasses = objc_getClassList( nullptr, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + struct StringHolder : MatcherBase<NSString*>{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + bool match( NSString* arg ) const override { + return false; + } + + NSString* CATCH_ARC_STRONG m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + std::string describe() const override { + return "equals string: " + Catch::Detail::stringify( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + std::string describe() const override { + return "contains string: " + Catch::Detail::stringify( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + std::string describe() const override { + return "starts with: " + Catch::Detail::stringify( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + std::string describe() const override { + return "ends with: " + Catch::Detail::stringify( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix +#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ ++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ +{ \ +return @ name; \ +} \ ++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ +{ \ +return @ desc; \ +} \ +-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) + +#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) + +// end catch_objc.hpp +#endif + +#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES +// start catch_external_interfaces.h + +// start catch_reporter_bases.hpp + +// start catch_interfaces_reporter.h + +// start catch_config.hpp + +// start catch_test_spec_parser.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_test_spec.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_wildcard_pattern.h + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ); + virtual ~WildcardPattern() = default; + virtual bool matches( std::string const& str ) const; + + private: + std::string adjustCase( std::string const& str ) const; + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard = NoWildcard; + std::string m_pattern; + }; +} + +// end catch_wildcard_pattern.h +#include <string> +#include <vector> +#include <memory> + +namespace Catch { + + class TestSpec { + struct Pattern { + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + }; + using PatternPtr = std::shared_ptr<Pattern>; + + class NamePattern : public Pattern { + public: + NamePattern( std::string const& name ); + virtual ~NamePattern(); + virtual bool matches( TestCaseInfo const& testCase ) const override; + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern( std::string const& tag ); + virtual ~TagPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const override; + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern( PatternPtr const& underlyingPattern ); + virtual ~ExcludedPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const override; + private: + PatternPtr m_underlyingPattern; + }; + + struct Filter { + std::vector<PatternPtr> m_patterns; + + bool matches( TestCaseInfo const& testCase ) const; + }; + + public: + bool hasFilters() const; + bool matches( TestCaseInfo const& testCase ) const; + + private: + std::vector<Filter> m_filters; + + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec.h +// start catch_interfaces_tag_alias_registry.h + +#include <string> + +namespace Catch { + + struct TagAlias; + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + // Nullptr if not present + virtual TagAlias const* find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +// end catch_interfaces_tag_alias_registry.h +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode = None; + bool m_exclusion = false; + std::size_t m_start = std::string::npos, m_pos = 0; + std::string m_arg; + std::vector<std::size_t> m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases = nullptr; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ); + + TestSpecParser& parse( std::string const& arg ); + TestSpec testSpec(); + + private: + void visitChar( char c ); + void startNewMode( Mode mode, std::size_t start ); + void escape(); + std::string subString() const; + + template<typename T> + void addPattern() { + std::string token = subString(); + for( std::size_t i = 0; i < m_escapeChars.size(); ++i ) + token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); + m_escapeChars.clear(); + if( startsWith( token, "exclude:" ) ) { + m_exclusion = true; + token = token.substr( 8 ); + } + if( !token.empty() ) { + TestSpec::PatternPtr pattern = std::make_shared<T>( token ); + if( m_exclusion ) + pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern ); + m_currentFilter.m_patterns.push_back( pattern ); + } + m_exclusion = false; + m_mode = None; + } + + void addFilter(); + }; + TestSpec parseTestSpec( std::string const& arg ); + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec_parser.h +// start catch_interfaces_config.h + +#include <iosfwd> +#include <string> +#include <vector> +#include <memory> + +namespace Catch { + + enum class Verbosity { + Quiet = 0, + Normal, + High + }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01, + NoTests = 0x02 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + struct WaitForKeypress { enum When { + Never, + BeforeStart = 1, + BeforeExit = 2, + BeforeStartAndExit = BeforeStart | BeforeExit + }; }; + + class TestSpec; + + struct IConfig : NonCopyable { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual bool warnAboutNoTests() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual bool hasTestFilters() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual int benchmarkResolutionMultiple() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector<std::string> const& getSectionsToRun() const = 0; + virtual Verbosity verbosity() const = 0; + }; + + using IConfigPtr = std::shared_ptr<IConfig const>; +} + +// end catch_interfaces_config.h +// Libstdc++ doesn't like incomplete classes for unique_ptr + +#include <memory> +#include <vector> +#include <string> + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct IStream; + + struct ConfigData { + bool listTests = false; + bool listTags = false; + bool listReporters = false; + bool listTestNamesOnly = false; + + bool showSuccessfulTests = false; + bool shouldDebugBreak = false; + bool noThrow = false; + bool showHelp = false; + bool showInvisibles = false; + bool filenamesAsTags = false; + bool libIdentify = false; + + int abortAfter = -1; + unsigned int rngSeed = 0; + int benchmarkResolutionMultiple = 100; + + Verbosity verbosity = Verbosity::Normal; + WarnAbout::What warnings = WarnAbout::Nothing; + ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; + RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; + UseColour::YesOrNo useColour = UseColour::Auto; + WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; + + std::string outputFilename; + std::string name; + std::string processName; + + std::vector<std::string> reporterNames; + std::vector<std::string> testsOrTags; + std::vector<std::string> sectionsToRun; + }; + + class Config : public IConfig { + public: + + Config() = default; + Config( ConfigData const& data ); + virtual ~Config() = default; + + std::string const& getFilename() const; + + bool listTests() const; + bool listTestNamesOnly() const; + bool listTags() const; + bool listReporters() const; + + std::string getProcessName() const; + + std::vector<std::string> const& getReporterNames() const; + std::vector<std::string> const& getTestsOrTags() const; + std::vector<std::string> const& getSectionsToRun() const override; + + virtual TestSpec const& testSpec() const override; + bool hasTestFilters() const override; + + bool showHelp() const; + + // IConfig interface + bool allowThrows() const override; + std::ostream& stream() const override; + std::string name() const override; + bool includeSuccessfulResults() const override; + bool warnAboutMissingAssertions() const override; + bool warnAboutNoTests() const override; + ShowDurations::OrNot showDurations() const override; + RunTests::InWhatOrder runOrder() const override; + unsigned int rngSeed() const override; + int benchmarkResolutionMultiple() const override; + UseColour::YesOrNo useColour() const override; + bool shouldDebugBreak() const override; + int abortAfter() const override; + bool showInvisibles() const override; + Verbosity verbosity() const override; + + private: + + IStream const* openStream(); + ConfigData m_data; + + std::unique_ptr<IStream const> m_stream; + TestSpec m_testSpec; + bool m_hasTestFilters = false; + }; + +} // end namespace Catch + +// end catch_config.hpp +// start catch_assertionresult.h + +#include <string> + +namespace Catch { + + struct AssertionResultData + { + AssertionResultData() = delete; + + AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ); + + std::string message; + mutable std::string reconstructedExpression; + LazyExpression lazyExpression; + ResultWas::OfType resultType; + + std::string reconstructExpression() const; + }; + + class AssertionResult { + public: + AssertionResult() = delete; + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + StringRef getTestMacroName() const; + + //protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +// end catch_assertionresult.h +// start catch_option.hpp + +namespace Catch { + + // An optional type + template<typename T> + class Option { + public: + Option() : nullableValue( nullptr ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : nullptr ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = nullptr; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != nullptr; } + bool none() const { return nullableValue == nullptr; } + + bool operator !() const { return nullableValue == nullptr; } + explicit operator bool() const { + return some(); + } + + private: + T *nullableValue; + alignas(alignof(T)) char storage[sizeof(T)]; + }; + +} // end namespace Catch + +// end catch_option.hpp +#include <string> +#include <iosfwd> +#include <map> +#include <set> +#include <memory> + +namespace Catch { + + struct ReporterConfig { + explicit ReporterConfig( IConfigPtr const& _fullConfig ); + + ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ); + + std::ostream& stream() const; + IConfigPtr fullConfig() const; + + private: + std::ostream* m_stream; + IConfigPtr m_fullConfig; + }; + + struct ReporterPreferences { + bool shouldRedirectStdOut = false; + }; + + template<typename T> + struct LazyStat : Option<T> { + LazyStat& operator=( T const& _value ) { + Option<T>::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option<T>::reset(); + used = false; + } + bool used = false; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ); + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ); + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector<MessageInfo> const& _infoMessages, + Totals const& _totals ); + + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = default; + AssertionStats& operator = ( AssertionStats && ) = default; + virtual ~AssertionStats(); + + AssertionResult assertionResult; + std::vector<MessageInfo> infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ); + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; + virtual ~SectionStats(); + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ); + + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; + virtual ~TestCaseStats(); + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ); + TestGroupStats( GroupInfo const& _groupInfo ); + + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; + virtual ~TestGroupStats(); + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ); + + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; + virtual ~TestRunStats(); + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + struct BenchmarkInfo { + std::string name; + }; + struct BenchmarkStats { + BenchmarkInfo info; + std::size_t iterations; + uint64_t elapsedTimeInNanoseconds; + }; + + struct IStreamingReporter { + virtual ~IStreamingReporter() = default; + + // Implementing class must also provide the following static methods: + // static std::string getDescription(); + // static std::set<Verbosity> getSupportedVerbosities() + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + // *** experimental *** + virtual void benchmarkStarting( BenchmarkInfo const& ) {} + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + // *** experimental *** + virtual void benchmarkEnded( BenchmarkStats const& ) {} + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + // Default empty implementation provided + virtual void fatalErrorEncountered( StringRef name ); + + virtual bool isMulti() const; + }; + using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>; + + struct IReporterFactory { + virtual ~IReporterFactory(); + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; + + struct IReporterRegistry { + using FactoryMap = std::map<std::string, IReporterFactoryPtr>; + using Listeners = std::vector<IReporterFactoryPtr>; + + virtual ~IReporterRegistry(); + virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + + void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ); + +} // end namespace Catch + +// end catch_interfaces_reporter.h +#include <algorithm> +#include <cstring> +#include <cfloat> +#include <cstdio> +#include <assert.h> +#include <memory> +#include <ostream> + +namespace Catch { + void prepareExpandedExpression(AssertionResult& result); + + // Returns double formatted as %.3f (format expected on output) + std::string getFormattedDuration( double duration ); + + template<typename DerivedT> + struct StreamingReporterBase : IStreamingReporter { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) + throw std::domain_error( "Verbosity level not supported by this reporter" ); + } + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set<Verbosity> getSupportedVerbosities() { + return { Verbosity::Normal }; + } + + ~StreamingReporterBase() override = default; + + void noMatchingTestCases(std::string const&) override {} + + void testRunStarting(TestRunInfo const& _testRunInfo) override { + currentTestRunInfo = _testRunInfo; + } + void testGroupStarting(GroupInfo const& _groupInfo) override { + currentGroupInfo = _groupInfo; + } + + void testCaseStarting(TestCaseInfo const& _testInfo) override { + currentTestCaseInfo = _testInfo; + } + void sectionStarting(SectionInfo const& _sectionInfo) override { + m_sectionStack.push_back(_sectionInfo); + } + + void sectionEnded(SectionStats const& /* _sectionStats */) override { + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override { + currentTestCaseInfo.reset(); + } + void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override { + currentGroupInfo.reset(); + } + void testRunEnded(TestRunStats const& /* _testRunStats */) override { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + void skipTest(TestCaseInfo const&) override { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + IConfigPtr m_config; + std::ostream& stream; + + LazyStat<TestRunInfo> currentTestRunInfo; + LazyStat<GroupInfo> currentGroupInfo; + LazyStat<TestCaseInfo> currentTestCaseInfo; + + std::vector<SectionInfo> m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + template<typename DerivedT> + struct CumulativeReporterBase : IStreamingReporter { + template<typename T, typename ChildNodeT> + struct Node { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>; + T value; + ChildNodes children; + }; + struct SectionNode { + explicit SectionNode(SectionStats const& _stats) : stats(_stats) {} + virtual ~SectionNode() = default; + + bool operator == (SectionNode const& other) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == (std::shared_ptr<SectionNode> const& other) const { + return operator==(*other); + } + + SectionStats stats; + using ChildSections = std::vector<std::shared_ptr<SectionNode>>; + using Assertions = std::vector<AssertionStats>; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() (std::shared_ptr<SectionNode> const& node) const { + return ((node->stats.sectionInfo.name == m_other.name) && + (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); + } + void operator=(BySectionInfo const&) = delete; + + private: + SectionInfo const& m_other; + }; + + using TestCaseNode = Node<TestCaseStats, SectionNode>; + using TestGroupNode = Node<TestGroupStats, TestCaseNode>; + using TestRunNode = Node<TestRunStats, TestGroupNode>; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) + throw std::domain_error( "Verbosity level not supported by this reporter" ); + } + ~CumulativeReporterBase() override = default; + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set<Verbosity> getSupportedVerbosities() { + return { Verbosity::Normal }; + } + + void testRunStarting( TestRunInfo const& ) override {} + void testGroupStarting( GroupInfo const& ) override {} + + void testCaseStarting( TestCaseInfo const& ) override {} + + void sectionStarting( SectionInfo const& sectionInfo ) override { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + std::shared_ptr<SectionNode> node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = std::make_shared<SectionNode>( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + auto it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = std::make_shared<SectionNode>( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = std::move(node); + } + + void assertionStarting(AssertionInfo const&) override {} + + bool assertionEnded(AssertionStats const& assertionStats) override { + assert(!m_sectionStack.empty()); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back(assertionStats); + return true; + } + void sectionEnded(SectionStats const& sectionStats) override { + assert(!m_sectionStack.empty()); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const& testCaseStats) override { + auto node = std::make_shared<TestCaseNode>(testCaseStats); + assert(m_sectionStack.size() == 0); + node->children.push_back(m_rootSection); + m_testCases.push_back(node); + m_rootSection.reset(); + + assert(m_deepestSection); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + void testGroupEnded(TestGroupStats const& testGroupStats) override { + auto node = std::make_shared<TestGroupNode>(testGroupStats); + node->children.swap(m_testCases); + m_testGroups.push_back(node); + } + void testRunEnded(TestRunStats const& testRunStats) override { + auto node = std::make_shared<TestRunNode>(testRunStats); + node->children.swap(m_testGroups); + m_testRuns.push_back(node); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + void skipTest(TestCaseInfo const&) override {} + + IConfigPtr m_config; + std::ostream& stream; + std::vector<AssertionStats> m_assertions; + std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections; + std::vector<std::shared_ptr<TestCaseNode>> m_testCases; + std::vector<std::shared_ptr<TestGroupNode>> m_testGroups; + + std::vector<std::shared_ptr<TestRunNode>> m_testRuns; + + std::shared_ptr<SectionNode> m_rootSection; + std::shared_ptr<SectionNode> m_deepestSection; + std::vector<std::shared_ptr<SectionNode>> m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + template<char C> + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> { + TestEventListenerBase( ReporterConfig const& _config ); + + void assertionStarting(AssertionInfo const&) override; + bool assertionEnded(AssertionStats const&) override; + }; + +} // end namespace Catch + +// end catch_reporter_bases.hpp +// start catch_console_colour.h + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + BrightYellow = Bright | Yellow, + + // By intention + FileName = LightGrey, + Warning = BrightYellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = BrightYellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour&& other ) noexcept; + Colour& operator=( Colour&& other ) noexcept; + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved = false; + }; + + std::ostream& operator << ( std::ostream& os, Colour const& ); + +} // end namespace Catch + +// end catch_console_colour.h +// start catch_reporter_registrars.hpp + + +namespace Catch { + + template<typename T> + class ReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override { + return std::unique_ptr<T>( new T( config ) ); + } + + virtual std::string getDescription() const override { + return T::getDescription(); + } + }; + + public: + + explicit ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() ); + } + }; + + template<typename T> + class ListenerRegistrar { + + class ListenerFactory : public IReporterFactory { + + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override { + return std::unique_ptr<T>( new T( config ) ); + } + virtual std::string getDescription() const override { + return std::string(); + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() ); + } + }; +} + +#if !defined(CATCH_CONFIG_DISABLE) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +#define CATCH_REGISTER_LISTENER( listenerType ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#else // CATCH_CONFIG_DISABLE + +#define CATCH_REGISTER_REPORTER(name, reporterType) +#define CATCH_REGISTER_LISTENER(listenerType) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_reporter_registrars.hpp +// Allow users to base their work off existing reporters +// start catch_reporter_compact.h + +namespace Catch { + + struct CompactReporter : StreamingReporterBase<CompactReporter> { + + using StreamingReporterBase::StreamingReporterBase; + + ~CompactReporter() override; + + static std::string getDescription(); + + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases(std::string const& spec) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& _assertionStats) override; + + void sectionEnded(SectionStats const& _sectionStats) override; + + void testRunEnded(TestRunStats const& _testRunStats) override; + + }; + +} // end namespace Catch + +// end catch_reporter_compact.h +// start catch_reporter_console.h + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + // Fwd decls + struct SummaryColumn; + class TablePrinter; + + struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> { + std::unique_ptr<TablePrinter> m_tablePrinter; + + ConsoleReporter(ReporterConfig const& config); + ~ConsoleReporter() override; + static std::string getDescription(); + + void noMatchingTestCases(std::string const& spec) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& _assertionStats) override; + + void sectionStarting(SectionInfo const& _sectionInfo) override; + void sectionEnded(SectionStats const& _sectionStats) override; + + void benchmarkStarting(BenchmarkInfo const& info) override; + void benchmarkEnded(BenchmarkStats const& stats) override; + + void testCaseEnded(TestCaseStats const& _testCaseStats) override; + void testGroupEnded(TestGroupStats const& _testGroupStats) override; + void testRunEnded(TestRunStats const& _testRunStats) override; + + private: + + void lazyPrint(); + + void lazyPrintWithoutClosingBenchmarkTable(); + void lazyPrintRunInfo(); + void lazyPrintGroupInfo(); + void printTestCaseAndSectionHeader(); + + void printClosedHeader(std::string const& _name); + void printOpenHeader(std::string const& _name); + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString(std::string const& _string, std::size_t indent = 0); + + void printTotals(Totals const& totals); + void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row); + + void printTotalsDivider(Totals const& totals); + void printSummaryDivider(); + + private: + bool m_headerPrinted = false; + }; + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +// end catch_reporter_console.h +// start catch_reporter_junit.h + +// start catch_xmlwriter.h + +#include <vector> + +namespace Catch { + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); + + void encodeTo( std::ostream& os ) const; + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ); + + ScopedElement( ScopedElement&& other ) noexcept; + ScopedElement& operator=( ScopedElement&& other ) noexcept; + + ~ScopedElement(); + + ScopedElement& writeText( std::string const& text, bool indent = true ); + + template<typename T> + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer = nullptr; + }; + + XmlWriter( std::ostream& os = Catch::cout() ); + ~XmlWriter(); + + XmlWriter( XmlWriter const& ) = delete; + XmlWriter& operator=( XmlWriter const& ) = delete; + + XmlWriter& startElement( std::string const& name ); + + ScopedElement scopedElement( std::string const& name ); + + XmlWriter& endElement(); + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); + + XmlWriter& writeAttribute( std::string const& name, bool attribute ); + + template<typename T> + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + ReusableStringStream rss; + rss << attribute; + return writeAttribute( name, rss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ); + + XmlWriter& writeComment( std::string const& text ); + + void writeStylesheetRef( std::string const& url ); + + XmlWriter& writeBlankLine(); + + void ensureTagClosed(); + + private: + + void writeDeclaration(); + + void newlineIfNecessary(); + + bool m_tagIsOpen = false; + bool m_needsNewline = false; + std::vector<std::string> m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +} + +// end catch_xmlwriter.h +namespace Catch { + + class JunitReporter : public CumulativeReporterBase<JunitReporter> { + public: + JunitReporter(ReporterConfig const& _config); + + ~JunitReporter() override; + + static std::string getDescription(); + + void noMatchingTestCases(std::string const& /*spec*/) override; + + void testRunStarting(TestRunInfo const& runInfo) override; + + void testGroupStarting(GroupInfo const& groupInfo) override; + + void testCaseStarting(TestCaseInfo const& testCaseInfo) override; + bool assertionEnded(AssertionStats const& assertionStats) override; + + void testCaseEnded(TestCaseStats const& testCaseStats) override; + + void testGroupEnded(TestGroupStats const& testGroupStats) override; + + void testRunEndedCumulative() override; + + void writeGroup(TestGroupNode const& groupNode, double suiteTime); + + void writeTestCase(TestCaseNode const& testCaseNode); + + void writeSection(std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode); + + void writeAssertions(SectionNode const& sectionNode); + void writeAssertion(AssertionStats const& stats); + + XmlWriter xml; + Timer suiteTimer; + std::string stdOutForSuite; + std::string stdErrForSuite; + unsigned int unexpectedExceptions = 0; + bool m_okToFail = false; + }; + +} // end namespace Catch + +// end catch_reporter_junit.h +// start catch_reporter_xml.h + +namespace Catch { + class XmlReporter : public StreamingReporterBase<XmlReporter> { + public: + XmlReporter(ReporterConfig const& _config); + + ~XmlReporter() override; + + static std::string getDescription(); + + virtual std::string getStylesheetRef() const; + + void writeSourceInfo(SourceLineInfo const& sourceInfo); + + public: // StreamingReporterBase + + void noMatchingTestCases(std::string const& s) override; + + void testRunStarting(TestRunInfo const& testInfo) override; + + void testGroupStarting(GroupInfo const& groupInfo) override; + + void testCaseStarting(TestCaseInfo const& testInfo) override; + + void sectionStarting(SectionInfo const& sectionInfo) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& assertionStats) override; + + void sectionEnded(SectionStats const& sectionStats) override; + + void testCaseEnded(TestCaseStats const& testCaseStats) override; + + void testGroupEnded(TestGroupStats const& testGroupStats) override; + + void testRunEnded(TestRunStats const& testRunStats) override; + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth = 0; + }; + +} // end namespace Catch + +// end catch_reporter_xml.h + +// end catch_external_interfaces.h +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +#ifdef CATCH_IMPL +// start catch_impl.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// Keep these here for external reporters +// start catch_test_case_tracker.h + +#include <string> +#include <vector> +#include <memory> + +namespace Catch { +namespace TestCaseTracking { + + struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); + }; + + struct ITracker; + + using ITrackerPtr = std::shared_ptr<ITracker>; + + struct ITracker { + virtual ~ITracker(); + + // static queries + virtual NameAndLocation const& nameAndLocation() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( ITrackerPtr const& child ) = 0; + virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + ITrackerPtr m_rootTracker; + ITracker* m_currentTracker = nullptr; + RunState m_runState = NotStarted; + + public: + + static TrackerContext& instance(); + + ITracker& startRun(); + void endRun(); + + void startCycle(); + void completeCycle(); + + bool completedCycle() const; + ITracker& currentTracker(); + void setCurrentTracker( ITracker* tracker ); + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + + class TrackerHasName { + NameAndLocation m_nameAndLocation; + public: + TrackerHasName( NameAndLocation const& nameAndLocation ); + bool operator ()( ITrackerPtr const& tracker ) const; + }; + + using Children = std::vector<ITrackerPtr>; + NameAndLocation m_nameAndLocation; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState = NotStarted; + + public: + TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + + NameAndLocation const& nameAndLocation() const override; + bool isComplete() const override; + bool isSuccessfullyCompleted() const override; + bool isOpen() const override; + bool hasChildren() const override; + + void addChild( ITrackerPtr const& child ) override; + + ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; + ITracker& parent() override; + + void openChild() override; + + bool isSectionTracker() const override; + bool isIndexTracker() const override; + + void open(); + + void close() override; + void fail() override; + void markAsNeedingAnotherRun() override; + + private: + void moveToParent(); + void moveToThis(); + }; + + class SectionTracker : public TrackerBase { + std::vector<std::string> m_filters; + public: + SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + + bool isSectionTracker() const override; + + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); + + void tryOpen(); + + void addInitialFilters( std::vector<std::string> const& filters ); + void addNextFilters( std::vector<std::string> const& filters ); + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index = -1; + public: + IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ); + + bool isIndexTracker() const override; + void close() override; + + static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ); + + int index() const; + + void moveNext(); + }; + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +// end catch_test_case_tracker.h + +// start catch_leak_detector.h + +namespace Catch { + + struct LeakDetector { + LeakDetector(); + }; + +} +// end catch_leak_detector.h +// Cpp files will be included in the single-header file here +// start catch_approx.cpp + +#include <cmath> +#include <limits> + +namespace { + +// Performs equivalent check of std::fabs(lhs - rhs) <= margin +// But without the subtraction to allow for INFINITY in comparison +bool marginComparison(double lhs, double rhs, double margin) { + return (lhs + margin >= rhs) && (rhs + margin >= lhs); +} + +} + +namespace Catch { +namespace Detail { + + Approx::Approx ( double value ) + : m_epsilon( std::numeric_limits<float>::epsilon()*100 ), + m_margin( 0.0 ), + m_scale( 0.0 ), + m_value( value ) + {} + + Approx Approx::custom() { + return Approx( 0 ); + } + + std::string Approx::toString() const { + ReusableStringStream rss; + rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )"; + return rss.str(); + } + + bool Approx::equalityComparisonImpl(const double other) const { + // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value + // Thanks to Richard Harris for his help refining the scaled margin value + return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value))); + } + +} // end namespace Detail + +std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) { + return value.toString(); +} + +} // end namespace Catch +// end catch_approx.cpp +// start catch_assertionhandler.cpp + +// start catch_context.h + +#include <memory> + +namespace Catch { + + struct IResultCapture; + struct IRunner; + struct IConfig; + struct IMutableContext; + + using IConfigPtr = std::shared_ptr<IConfig const>; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual IConfigPtr const& getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( IConfigPtr const& config ) = 0; + + private: + static IMutableContext *currentContext; + friend IMutableContext& getCurrentMutableContext(); + friend void cleanUpContext(); + static void createContext(); + }; + + inline IMutableContext& getCurrentMutableContext() + { + if( !IMutableContext::currentContext ) + IMutableContext::createContext(); + return *IMutableContext::currentContext; + } + + inline IContext& getCurrentContext() + { + return getCurrentMutableContext(); + } + + void cleanUpContext(); +} + +// end catch_context.h +// start catch_debugger.h + +namespace Catch { + bool isDebuggerActive(); +} + +#ifdef CATCH_PLATFORM_MAC + + #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ + #else // Fall back to the generic way. + #include <signal.h> + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } +#else + namespace Catch { + inline void doNothing() {} + } + #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing() +#endif + +// end catch_debugger.h +// start catch_run_context.h + +// start catch_fatal_condition.h + +// start catch_windows_h_proxy.h + + +#if defined(CATCH_PLATFORM_WINDOWS) + +#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINED_NOMINMAX +# define NOMINMAX +#endif +#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include <AfxWin.h> +#else +#include <windows.h> +#endif + +#ifdef CATCH_DEFINED_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + +#endif // defined(CATCH_PLATFORM_WINDOWS) + +// end catch_windows_h_proxy.h +#if defined( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + + struct FatalConditionHandler { + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); + FatalConditionHandler(); + static void reset(); + ~FatalConditionHandler(); + + private: + static bool isSet; + static ULONG guaranteeSize; + static PVOID exceptionHandlerHandle; + }; + +} // namespace Catch + +#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) + +#include <signal.h> + +namespace Catch { + + struct FatalConditionHandler { + + static bool isSet; + static struct sigaction oldSigActions[]; + static stack_t oldSigStack; + static char altStackMem[]; + + static void handleSignal( int sig ); + + FatalConditionHandler(); + ~FatalConditionHandler(); + static void reset(); + }; + +} // namespace Catch + +#else + +namespace Catch { + struct FatalConditionHandler { + void reset(); + }; +} + +#endif + +// end catch_fatal_condition.h +#include <string> + +namespace Catch { + + struct IMutableContext; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + public: + RunContext( RunContext const& ) = delete; + RunContext& operator =( RunContext const& ) = delete; + + explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter ); + + ~RunContext() override; + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ); + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ); + + Totals runTest(TestCase const& testCase); + + IConfigPtr config() const; + IStreamingReporter& reporter() const; + + public: // IResultCapture + + // Assertion handlers + void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) override; + void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction ) override; + void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) override; + void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction ) override; + void handleIncomplete + ( AssertionInfo const& info ) override; + void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) override; + + bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override; + + void sectionEnded( SectionEndInfo const& endInfo ) override; + void sectionEndedEarly( SectionEndInfo const& endInfo ) override; + + void benchmarkStarting( BenchmarkInfo const& info ) override; + void benchmarkEnded( BenchmarkStats const& stats ) override; + + void pushScopedMessage( MessageInfo const& message ) override; + void popScopedMessage( MessageInfo const& message ) override; + + std::string getCurrentTestName() const override; + + const AssertionResult* getLastResult() const override; + + void exceptionEarlyReported() override; + + void handleFatalErrorCondition( StringRef message ) override; + + bool lastAssertionPassed() override; + + void assertionPassed() override; + + public: + // !TBD We need to do this another way! + bool aborting() const final; + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ); + void invokeActiveTestCase(); + + void resetAssertionInfo(); + bool testForMissingAssertions( Counts& assertions ); + + void assertionEnded( AssertionResult const& result ); + void reportExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + ITransientExpression const *expr, + bool negated ); + + void populateReaction( AssertionReaction& reaction ); + + private: + + void handleUnfinishedSections(); + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase = nullptr; + ITracker* m_testCaseTracker; + Option<AssertionResult> m_lastResult; + + IConfigPtr m_config; + Totals m_totals; + IStreamingReporterPtr m_reporter; + std::vector<MessageInfo> m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector<SectionEndInfo> m_unfinishedSections; + std::vector<ITracker*> m_activeSections; + TrackerContext m_trackerContext; + bool m_lastAssertionPassed = false; + bool m_shouldReportUnexpected = true; + bool m_includeSuccessfulResults; + }; + +} // end namespace Catch + +// end catch_run_context.h +namespace Catch { + + auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { + expr.streamReconstructedExpression( os ); + return os; + } + + LazyExpression::LazyExpression( bool isNegated ) + : m_isNegated( isNegated ) + {} + + LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} + + LazyExpression::operator bool() const { + return m_transientExpression != nullptr; + } + + auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { + if( lazyExpr.m_isNegated ) + os << "!"; + + if( lazyExpr ) { + if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) + os << "(" << *lazyExpr.m_transientExpression << ")"; + else + os << *lazyExpr.m_transientExpression; + } + else { + os << "{** error - unchecked empty expression requested **}"; + } + return os; + } + + AssertionHandler::AssertionHandler + ( StringRef macroName, + SourceLineInfo const& lineInfo, + StringRef capturedExpression, + ResultDisposition::Flags resultDisposition ) + : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, + m_resultCapture( getResultCapture() ) + {} + + void AssertionHandler::handleExpr( ITransientExpression const& expr ) { + m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); + } + void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) { + m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); + } + + auto AssertionHandler::allowThrows() const -> bool { + return getCurrentContext().getConfig()->allowThrows(); + } + + void AssertionHandler::complete() { + setCompleted(); + if( m_reaction.shouldDebugBreak ) { + + // If you find your debugger stopping you here then go one level up on the + // call-stack for the code that caused it (typically a failed assertion) + + // (To go back to the test and change execution, jump over the throw, next) + CATCH_BREAK_INTO_DEBUGGER(); + } + if( m_reaction.shouldThrow ) + throw Catch::TestFailureException(); + } + void AssertionHandler::setCompleted() { + m_completed = true; + } + + void AssertionHandler::handleUnexpectedInflightException() { + m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction ); + } + + void AssertionHandler::handleExceptionThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + void AssertionHandler::handleExceptionNotThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + + void AssertionHandler::handleUnexpectedExceptionNotThrown() { + m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction ); + } + + void AssertionHandler::handleThrowingCallSkipped() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + + // This is the overload that takes a string and infers the Equals matcher from it + // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp + void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ) { + handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); + } + +} // namespace Catch +// end catch_assertionhandler.cpp +// start catch_assertionresult.cpp + +namespace Catch { + AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression): + lazyExpression(_lazyExpression), + resultType(_resultType) {} + + std::string AssertionResultData::reconstructExpression() const { + + if( reconstructedExpression.empty() ) { + if( lazyExpression ) { + ReusableStringStream rss; + rss << lazyExpression; + reconstructedExpression = rss.str(); + } + } + return reconstructedExpression; + } + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return m_info.capturedExpression[0] != 0; + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string AssertionResult::getExpression() const { + if( isFalseTest( m_info.resultDisposition ) ) + return "!(" + m_info.capturedExpression + ")"; + else + return m_info.capturedExpression; + } + + std::string AssertionResult::getExpressionInMacro() const { + std::string expr; + if( m_info.macroName[0] == 0 ) + expr = m_info.capturedExpression; + else { + expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 ); + expr += m_info.macroName; + expr += "( "; + expr += m_info.capturedExpression; + expr += " )"; + } + return expr; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + std::string expr = m_resultData.reconstructExpression(); + return expr.empty() + ? getExpression() + : expr; + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + StringRef AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + +} // end namespace Catch +// end catch_assertionresult.cpp +// start catch_benchmark.cpp + +namespace Catch { + + auto BenchmarkLooper::getResolution() -> uint64_t { + return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple(); + } + + void BenchmarkLooper::reportStart() { + getResultCapture().benchmarkStarting( { m_name } ); + } + auto BenchmarkLooper::needsMoreIterations() -> bool { + auto elapsed = m_timer.getElapsedNanoseconds(); + + // Exponentially increasing iterations until we're confident in our timer resolution + if( elapsed < m_resolution ) { + m_iterationsToRun *= 10; + return true; + } + + getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } ); + return false; + } + +} // end namespace Catch +// end catch_benchmark.cpp +// start catch_capture_matchers.cpp + +namespace Catch { + + using StringMatcher = Matchers::Impl::MatcherBase<std::string>; + + // This is the general overload that takes a any string matcher + // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers + // the Equals matcher (so the header does not mention matchers) + void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) { + std::string exceptionMessage = Catch::translateActiveException(); + MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString ); + handler.handleExpr( expr ); + } + +} // namespace Catch +// end catch_capture_matchers.cpp +// start catch_commandline.cpp + +// start catch_commandline.h + +// start catch_clara.h + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#endif +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#pragma clang diagnostic ignored "-Wshadow" +#endif + +// start clara.hpp +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See https://github.com/philsquared/Clara for more details + +// Clara v1.1.4 + + +#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 +#endif + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include(<optional>) && __cplusplus >= 201703L +#include <optional> +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + +// ----------- #included from clara_textflow.hpp ----------- + +// TextFlowCpp +// +// A single-header library for wrapping and laying out basic text, by Phil Nash +// +// This work is licensed under the BSD 2-Clause license. +// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause +// +// This project is hosted at https://github.com/philsquared/textflowcpp + + +#include <cassert> +#include <ostream> +#include <sstream> +#include <vector> + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { namespace clara { namespace TextFlow { + + inline auto isWhitespace( char c ) -> bool { + static std::string chars = " \t\n\r"; + return chars.find( c ) != std::string::npos; + } + inline auto isBreakableBefore( char c ) -> bool { + static std::string chars = "[({<|"; + return chars.find( c ) != std::string::npos; + } + inline auto isBreakableAfter( char c ) -> bool { + static std::string chars = "])}>.,:;*+-=&/\\"; + return chars.find( c ) != std::string::npos; + } + + class Columns; + + class Column { + std::vector<std::string> m_strings; + size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; + size_t m_indent = 0; + size_t m_initialIndent = std::string::npos; + + public: + class iterator { + friend Column; + + Column const& m_column; + size_t m_stringIndex = 0; + size_t m_pos = 0; + + size_t m_len = 0; + size_t m_end = 0; + bool m_suffix = false; + + iterator( Column const& column, size_t stringIndex ) + : m_column( column ), + m_stringIndex( stringIndex ) + {} + + auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; } + + auto isBoundary( size_t at ) const -> bool { + assert( at > 0 ); + assert( at <= line().size() ); + + return at == line().size() || + ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) || + isBreakableBefore( line()[at] ) || + isBreakableAfter( line()[at-1] ); + } + + void calcLength() { + assert( m_stringIndex < m_column.m_strings.size() ); + + m_suffix = false; + auto width = m_column.m_width-indent(); + m_end = m_pos; + while( m_end < line().size() && line()[m_end] != '\n' ) + ++m_end; + + if( m_end < m_pos + width ) { + m_len = m_end - m_pos; + } + else { + size_t len = width; + while (len > 0 && !isBoundary(m_pos + len)) + --len; + while (len > 0 && isWhitespace( line()[m_pos + len - 1] )) + --len; + + if (len > 0) { + m_len = len; + } else { + m_suffix = true; + m_len = width - 1; + } + } + } + + auto indent() const -> size_t { + auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; + return initial == std::string::npos ? m_column.m_indent : initial; + } + + auto addIndentAndSuffix(std::string const &plain) const -> std::string { + return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain); + } + + public: + explicit iterator( Column const& column ) : m_column( column ) { + assert( m_column.m_width > m_column.m_indent ); + assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent ); + calcLength(); + if( m_len == 0 ) + m_stringIndex++; // Empty string + } + + auto operator *() const -> std::string { + assert( m_stringIndex < m_column.m_strings.size() ); + assert( m_pos <= m_end ); + if( m_pos + m_column.m_width < m_end ) + return addIndentAndSuffix(line().substr(m_pos, m_len)); + else + return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos)); + } + + auto operator ++() -> iterator& { + m_pos += m_len; + if( m_pos < line().size() && line()[m_pos] == '\n' ) + m_pos += 1; + else + while( m_pos < line().size() && isWhitespace( line()[m_pos] ) ) + ++m_pos; + + if( m_pos == line().size() ) { + m_pos = 0; + ++m_stringIndex; + } + if( m_stringIndex < m_column.m_strings.size() ) + calcLength(); + return *this; + } + auto operator ++(int) -> iterator { + iterator prev( *this ); + operator++(); + return prev; + } + + auto operator ==( iterator const& other ) const -> bool { + return + m_pos == other.m_pos && + m_stringIndex == other.m_stringIndex && + &m_column == &other.m_column; + } + auto operator !=( iterator const& other ) const -> bool { + return !operator==( other ); + } + }; + using const_iterator = iterator; + + explicit Column( std::string const& text ) { m_strings.push_back( text ); } + + auto width( size_t newWidth ) -> Column& { + assert( newWidth > 0 ); + m_width = newWidth; + return *this; + } + auto indent( size_t newIndent ) -> Column& { + m_indent = newIndent; + return *this; + } + auto initialIndent( size_t newIndent ) -> Column& { + m_initialIndent = newIndent; + return *this; + } + + auto width() const -> size_t { return m_width; } + auto begin() const -> iterator { return iterator( *this ); } + auto end() const -> iterator { return { *this, m_strings.size() }; } + + inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) { + bool first = true; + for( auto line : col ) { + if( first ) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto operator + ( Column const& other ) -> Columns; + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + }; + + class Spacer : public Column { + + public: + explicit Spacer( size_t spaceWidth ) : Column( "" ) { + width( spaceWidth ); + } + }; + + class Columns { + std::vector<Column> m_columns; + + public: + + class iterator { + friend Columns; + struct EndTag {}; + + std::vector<Column> const& m_columns; + std::vector<Column::iterator> m_iterators; + size_t m_activeIterators; + + iterator( Columns const& columns, EndTag ) + : m_columns( columns.m_columns ), + m_activeIterators( 0 ) + { + m_iterators.reserve( m_columns.size() ); + + for( auto const& col : m_columns ) + m_iterators.push_back( col.end() ); + } + + public: + explicit iterator( Columns const& columns ) + : m_columns( columns.m_columns ), + m_activeIterators( m_columns.size() ) + { + m_iterators.reserve( m_columns.size() ); + + for( auto const& col : m_columns ) + m_iterators.push_back( col.begin() ); + } + + auto operator ==( iterator const& other ) const -> bool { + return m_iterators == other.m_iterators; + } + auto operator !=( iterator const& other ) const -> bool { + return m_iterators != other.m_iterators; + } + auto operator *() const -> std::string { + std::string row, padding; + + for( size_t i = 0; i < m_columns.size(); ++i ) { + auto width = m_columns[i].width(); + if( m_iterators[i] != m_columns[i].end() ) { + std::string col = *m_iterators[i]; + row += padding + col; + if( col.size() < width ) + padding = std::string( width - col.size(), ' ' ); + else + padding = ""; + } + else { + padding += std::string( width, ' ' ); + } + } + return row; + } + auto operator ++() -> iterator& { + for( size_t i = 0; i < m_columns.size(); ++i ) { + if (m_iterators[i] != m_columns[i].end()) + ++m_iterators[i]; + } + return *this; + } + auto operator ++(int) -> iterator { + iterator prev( *this ); + operator++(); + return prev; + } + }; + using const_iterator = iterator; + + auto begin() const -> iterator { return iterator( *this ); } + auto end() const -> iterator { return { *this, iterator::EndTag() }; } + + auto operator += ( Column const& col ) -> Columns& { + m_columns.push_back( col ); + return *this; + } + auto operator + ( Column const& col ) -> Columns { + Columns combined = *this; + combined += col; + return combined; + } + + inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) { + + bool first = true; + for( auto line : cols ) { + if( first ) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + }; + + inline auto Column::operator + ( Column const& other ) -> Columns { + Columns cols; + cols += *this; + cols += other; + return cols; + } +}}} // namespace Catch::clara::TextFlow + +// ----------- end of #include from clara_textflow.hpp ----------- +// ........... back in clara.hpp + +#include <memory> +#include <set> +#include <algorithm> + +#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) ) +#define CATCH_PLATFORM_WINDOWS +#endif + +namespace Catch { namespace clara { +namespace detail { + + // Traits for extracting arg and return type of lambdas (for single argument lambdas) + template<typename L> + struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {}; + + template<typename ClassT, typename ReturnT, typename... Args> + struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> { + static const bool isValid = false; + }; + + template<typename ClassT, typename ReturnT, typename ArgT> + struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> { + static const bool isValid = true; + using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type; + using ReturnType = ReturnT; + }; + + class TokenStream; + + // Transport for raw args (copied from main args, or supplied via init list for testing) + class Args { + friend TokenStream; + std::string m_exeName; + std::vector<std::string> m_args; + + public: + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} + + Args( std::initializer_list<std::string> args ) + : m_exeName( *args.begin() ), + m_args( args.begin()+1, args.end() ) + {} + + auto exeName() const -> std::string { + return m_exeName; + } + }; + + // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string + // may encode an option + its argument if the : or = form is used + enum class TokenType { + Option, Argument + }; + struct Token { + TokenType type; + std::string token; + }; + + inline auto isOptPrefix( char c ) -> bool { + return c == '-' +#ifdef CATCH_PLATFORM_WINDOWS + || c == '/' +#endif + ; + } + + // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled + class TokenStream { + using Iterator = std::vector<std::string>::const_iterator; + Iterator it; + Iterator itEnd; + std::vector<Token> m_tokenBuffer; + + void loadBuffer() { + m_tokenBuffer.resize( 0 ); + + // Skip any empty strings + while( it != itEnd && it->empty() ) + ++it; + + if( it != itEnd ) { + auto const &next = *it; + if( isOptPrefix( next[0] ) ) { + auto delimiterPos = next.find_first_of( " :=" ); + if( delimiterPos != std::string::npos ) { + m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } ); + m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } ); + } else { + if( next[1] != '-' && next.size() > 2 ) { + std::string opt = "- "; + for( size_t i = 1; i < next.size(); ++i ) { + opt[1] = next[i]; + m_tokenBuffer.push_back( { TokenType::Option, opt } ); + } + } else { + m_tokenBuffer.push_back( { TokenType::Option, next } ); + } + } + } else { + m_tokenBuffer.push_back( { TokenType::Argument, next } ); + } + } + } + + public: + explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {} + + TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) { + loadBuffer(); + } + + explicit operator bool() const { + return !m_tokenBuffer.empty() || it != itEnd; + } + + auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); } + + auto operator*() const -> Token { + assert( !m_tokenBuffer.empty() ); + return m_tokenBuffer.front(); + } + + auto operator->() const -> Token const * { + assert( !m_tokenBuffer.empty() ); + return &m_tokenBuffer.front(); + } + + auto operator++() -> TokenStream & { + if( m_tokenBuffer.size() >= 2 ) { + m_tokenBuffer.erase( m_tokenBuffer.begin() ); + } else { + if( it != itEnd ) + ++it; + loadBuffer(); + } + return *this; + } + }; + + class ResultBase { + public: + enum Type { + Ok, LogicError, RuntimeError + }; + + protected: + ResultBase( Type type ) : m_type( type ) {} + virtual ~ResultBase() = default; + + virtual void enforceOk() const = 0; + + Type m_type; + }; + + template<typename T> + class ResultValueBase : public ResultBase { + public: + auto value() const -> T const & { + enforceOk(); + return m_value; + } + + protected: + ResultValueBase( Type type ) : ResultBase( type ) {} + + ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) { + if( m_type == ResultBase::Ok ) + new( &m_value ) T( other.m_value ); + } + + ResultValueBase( Type, T const &value ) : ResultBase( Ok ) { + new( &m_value ) T( value ); + } + + auto operator=( ResultValueBase const &other ) -> ResultValueBase & { + if( m_type == ResultBase::Ok ) + m_value.~T(); + ResultBase::operator=(other); + if( m_type == ResultBase::Ok ) + new( &m_value ) T( other.m_value ); + return *this; + } + + ~ResultValueBase() override { + if( m_type == Ok ) + m_value.~T(); + } + + union { + T m_value; + }; + }; + + template<> + class ResultValueBase<void> : public ResultBase { + protected: + using ResultBase::ResultBase; + }; + + template<typename T = void> + class BasicResult : public ResultValueBase<T> { + public: + template<typename U> + explicit BasicResult( BasicResult<U> const &other ) + : ResultValueBase<T>( other.type() ), + m_errorMessage( other.errorMessage() ) + { + assert( type() != ResultBase::Ok ); + } + + template<typename U> + static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; } + static auto ok() -> BasicResult { return { ResultBase::Ok }; } + static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; } + static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; } + + explicit operator bool() const { return m_type == ResultBase::Ok; } + auto type() const -> ResultBase::Type { return m_type; } + auto errorMessage() const -> std::string { return m_errorMessage; } + + protected: + void enforceOk() const override { + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); + } + + std::string m_errorMessage; // Only populated if resultType is an error + + BasicResult( ResultBase::Type type, std::string const &message ) + : ResultValueBase<T>(type), + m_errorMessage(message) + { + assert( m_type != ResultBase::Ok ); + } + + using ResultValueBase<T>::ResultValueBase; + using ResultBase::m_type; + }; + + enum class ParseResultType { + Matched, NoMatch, ShortCircuitAll, ShortCircuitSame + }; + + class ParseState { + public: + + ParseState( ParseResultType type, TokenStream const &remainingTokens ) + : m_type(type), + m_remainingTokens( remainingTokens ) + {} + + auto type() const -> ParseResultType { return m_type; } + auto remainingTokens() const -> TokenStream { return m_remainingTokens; } + + private: + ParseResultType m_type; + TokenStream m_remainingTokens; + }; + + using Result = BasicResult<void>; + using ParserResult = BasicResult<ParseResultType>; + using InternalParseResult = BasicResult<ParseState>; + + struct HelpColumns { + std::string left; + std::string right; + }; + + template<typename T> + inline auto convertInto( std::string const &source, T& target ) -> ParserResult { + std::stringstream ss; + ss << source; + ss >> target; + if( ss.fail() ) + return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" ); + else + return ParserResult::ok( ParseResultType::Matched ); + } + inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult { + target = source; + return ParserResult::ok( ParseResultType::Matched ); + } + inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { + std::string srcLC = source; + std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } ); + if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") + target = true; + else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") + target = false; + else + return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template<typename T> + inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = std::move(temp); + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE + + struct NonCopyable { + NonCopyable() = default; + NonCopyable( NonCopyable const & ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable &operator=( NonCopyable const & ) = delete; + NonCopyable &operator=( NonCopyable && ) = delete; + }; + + struct BoundRef : NonCopyable { + virtual ~BoundRef() = default; + virtual auto isContainer() const -> bool { return false; } + virtual auto isFlag() const -> bool { return false; } + }; + struct BoundValueRefBase : BoundRef { + virtual auto setValue( std::string const &arg ) -> ParserResult = 0; + }; + struct BoundFlagRefBase : BoundRef { + virtual auto setFlag( bool flag ) -> ParserResult = 0; + virtual auto isFlag() const -> bool { return true; } + }; + + template<typename T> + struct BoundValueRef : BoundValueRefBase { + T &m_ref; + + explicit BoundValueRef( T &ref ) : m_ref( ref ) {} + + auto setValue( std::string const &arg ) -> ParserResult override { + return convertInto( arg, m_ref ); + } + }; + + template<typename T> + struct BoundValueRef<std::vector<T>> : BoundValueRefBase { + std::vector<T> &m_ref; + + explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {} + + auto isContainer() const -> bool override { return true; } + + auto setValue( std::string const &arg ) -> ParserResult override { + T temp; + auto result = convertInto( arg, temp ); + if( result ) + m_ref.push_back( temp ); + return result; + } + }; + + struct BoundFlagRef : BoundFlagRefBase { + bool &m_ref; + + explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {} + + auto setFlag( bool flag ) -> ParserResult override { + m_ref = flag; + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + template<typename ReturnType> + struct LambdaInvoker { + static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" ); + + template<typename L, typename ArgType> + static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { + return lambda( arg ); + } + }; + + template<> + struct LambdaInvoker<void> { + template<typename L, typename ArgType> + static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { + lambda( arg ); + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + template<typename ArgType, typename L> + inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult { + ArgType temp{}; + auto result = convertInto( arg, temp ); + return !result + ? result + : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp ); + } + + template<typename L> + struct BoundLambda : BoundValueRefBase { + L m_lambda; + + static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" ); + explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {} + + auto setValue( std::string const &arg ) -> ParserResult override { + return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg ); + } + }; + + template<typename L> + struct BoundFlagLambda : BoundFlagRefBase { + L m_lambda; + + static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" ); + static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" ); + + explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {} + + auto setFlag( bool flag ) -> ParserResult override { + return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag ); + } + }; + + enum class Optionality { Optional, Required }; + + struct Parser; + + class ParserBase { + public: + virtual ~ParserBase() = default; + virtual auto validate() const -> Result { return Result::ok(); } + virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0; + virtual auto cardinality() const -> size_t { return 1; } + + auto parse( Args const &args ) const -> InternalParseResult { + return parse( args.exeName(), TokenStream( args ) ); + } + }; + + template<typename DerivedT> + class ComposableParserImpl : public ParserBase { + public: + template<typename T> + auto operator|( T const &other ) const -> Parser; + + template<typename T> + auto operator+( T const &other ) const -> Parser; + }; + + // Common code and state for Args and Opts + template<typename DerivedT> + class ParserRefImpl : public ComposableParserImpl<DerivedT> { + protected: + Optionality m_optionality = Optionality::Optional; + std::shared_ptr<BoundRef> m_ref; + std::string m_hint; + std::string m_description; + + explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {} + + public: + template<typename T> + ParserRefImpl( T &ref, std::string const &hint ) + : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ), + m_hint( hint ) + {} + + template<typename LambdaT> + ParserRefImpl( LambdaT const &ref, std::string const &hint ) + : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ), + m_hint(hint) + {} + + auto operator()( std::string const &description ) -> DerivedT & { + m_description = description; + return static_cast<DerivedT &>( *this ); + } + + auto optional() -> DerivedT & { + m_optionality = Optionality::Optional; + return static_cast<DerivedT &>( *this ); + }; + + auto required() -> DerivedT & { + m_optionality = Optionality::Required; + return static_cast<DerivedT &>( *this ); + }; + + auto isOptional() const -> bool { + return m_optionality == Optionality::Optional; + } + + auto cardinality() const -> size_t override { + if( m_ref->isContainer() ) + return 0; + else + return 1; + } + + auto hint() const -> std::string { return m_hint; } + }; + + class ExeName : public ComposableParserImpl<ExeName> { + std::shared_ptr<std::string> m_name; + std::shared_ptr<BoundValueRefBase> m_ref; + + template<typename LambdaT> + static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> { + return std::make_shared<BoundLambda<LambdaT>>( lambda) ; + } + + public: + ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {} + + explicit ExeName( std::string &ref ) : ExeName() { + m_ref = std::make_shared<BoundValueRef<std::string>>( ref ); + } + + template<typename LambdaT> + explicit ExeName( LambdaT const& lambda ) : ExeName() { + m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda ); + } + + // The exe name is not parsed out of the normal tokens, but is handled specially + auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); + } + + auto name() const -> std::string { return *m_name; } + auto set( std::string const& newName ) -> ParserResult { + + auto lastSlash = newName.find_last_of( "\\/" ); + auto filename = ( lastSlash == std::string::npos ) + ? newName + : newName.substr( lastSlash+1 ); + + *m_name = filename; + if( m_ref ) + return m_ref->setValue( filename ); + else + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + class Arg : public ParserRefImpl<Arg> { + public: + using ParserRefImpl::ParserRefImpl; + + auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override { + auto validationResult = validate(); + if( !validationResult ) + return InternalParseResult( validationResult ); + + auto remainingTokens = tokens; + auto const &token = *remainingTokens; + if( token.type != TokenType::Argument ) + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); + + assert( !m_ref->isFlag() ); + auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); + + auto result = valueRef->setValue( remainingTokens->token ); + if( !result ) + return InternalParseResult( result ); + else + return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); + } + }; + + inline auto normaliseOpt( std::string const &optName ) -> std::string { +#ifdef CATCH_PLATFORM_WINDOWS + if( optName[0] == '/' ) + return "-" + optName.substr( 1 ); + else +#endif + return optName; + } + + class Opt : public ParserRefImpl<Opt> { + protected: + std::vector<std::string> m_optNames; + + public: + template<typename LambdaT> + explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {} + + explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {} + + template<typename LambdaT> + Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} + + template<typename T> + Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} + + auto operator[]( std::string const &optName ) -> Opt & { + m_optNames.push_back( optName ); + return *this; + } + + auto getHelpColumns() const -> std::vector<HelpColumns> { + std::ostringstream oss; + bool first = true; + for( auto const &opt : m_optNames ) { + if (first) + first = false; + else + oss << ", "; + oss << opt; + } + if( !m_hint.empty() ) + oss << " <" << m_hint << ">"; + return { { oss.str(), m_description } }; + } + + auto isMatch( std::string const &optToken ) const -> bool { + auto normalisedToken = normaliseOpt( optToken ); + for( auto const &name : m_optNames ) { + if( normaliseOpt( name ) == normalisedToken ) + return true; + } + return false; + } + + using ParserBase::parse; + + auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { + auto validationResult = validate(); + if( !validationResult ) + return InternalParseResult( validationResult ); + + auto remainingTokens = tokens; + if( remainingTokens && remainingTokens->type == TokenType::Option ) { + auto const &token = *remainingTokens; + if( isMatch(token.token ) ) { + if( m_ref->isFlag() ) { + auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() ); + auto result = flagRef->setFlag( true ); + if( !result ) + return InternalParseResult( result ); + if( result.value() == ParseResultType::ShortCircuitAll ) + return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); + } else { + auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); + ++remainingTokens; + if( !remainingTokens ) + return InternalParseResult::runtimeError( "Expected argument following " + token.token ); + auto const &argToken = *remainingTokens; + if( argToken.type != TokenType::Argument ) + return InternalParseResult::runtimeError( "Expected argument following " + token.token ); + auto result = valueRef->setValue( argToken.token ); + if( !result ) + return InternalParseResult( result ); + if( result.value() == ParseResultType::ShortCircuitAll ) + return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); + } + return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); + } + } + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); + } + + auto validate() const -> Result override { + if( m_optNames.empty() ) + return Result::logicError( "No options supplied to Opt" ); + for( auto const &name : m_optNames ) { + if( name.empty() ) + return Result::logicError( "Option name cannot be empty" ); +#ifdef CATCH_PLATFORM_WINDOWS + if( name[0] != '-' && name[0] != '/' ) + return Result::logicError( "Option name must begin with '-' or '/'" ); +#else + if( name[0] != '-' ) + return Result::logicError( "Option name must begin with '-'" ); +#endif + } + return ParserRefImpl::validate(); + } + }; + + struct Help : Opt { + Help( bool &showHelpFlag ) + : Opt([&]( bool flag ) { + showHelpFlag = flag; + return ParserResult::ok( ParseResultType::ShortCircuitAll ); + }) + { + static_cast<Opt &>( *this ) + ("display usage information") + ["-?"]["-h"]["--help"] + .optional(); + } + }; + + struct Parser : ParserBase { + + mutable ExeName m_exeName; + std::vector<Opt> m_options; + std::vector<Arg> m_args; + + auto operator|=( ExeName const &exeName ) -> Parser & { + m_exeName = exeName; + return *this; + } + + auto operator|=( Arg const &arg ) -> Parser & { + m_args.push_back(arg); + return *this; + } + + auto operator|=( Opt const &opt ) -> Parser & { + m_options.push_back(opt); + return *this; + } + + auto operator|=( Parser const &other ) -> Parser & { + m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end()); + m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end()); + return *this; + } + + template<typename T> + auto operator|( T const &other ) const -> Parser { + return Parser( *this ) |= other; + } + + // Forward deprecated interface with '+' instead of '|' + template<typename T> + auto operator+=( T const &other ) -> Parser & { return operator|=( other ); } + template<typename T> + auto operator+( T const &other ) const -> Parser { return operator|( other ); } + + auto getHelpColumns() const -> std::vector<HelpColumns> { + std::vector<HelpColumns> cols; + for (auto const &o : m_options) { + auto childCols = o.getHelpColumns(); + cols.insert( cols.end(), childCols.begin(), childCols.end() ); + } + return cols; + } + + void writeToStream( std::ostream &os ) const { + if (!m_exeName.name().empty()) { + os << "usage:\n" << " " << m_exeName.name() << " "; + bool required = true, first = true; + for( auto const &arg : m_args ) { + if (first) + first = false; + else + os << " "; + if( arg.isOptional() && required ) { + os << "["; + required = false; + } + os << "<" << arg.hint() << ">"; + if( arg.cardinality() == 0 ) + os << " ... "; + } + if( !required ) + os << "]"; + if( !m_options.empty() ) + os << " options"; + os << "\n\nwhere options are:" << std::endl; + } + + auto rows = getHelpColumns(); + size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH; + size_t optWidth = 0; + for( auto const &cols : rows ) + optWidth = (std::max)(optWidth, cols.left.size() + 2); + + optWidth = (std::min)(optWidth, consoleWidth/2); + + for( auto const &cols : rows ) { + auto row = + TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) + + TextFlow::Spacer(4) + + TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth ); + os << row << std::endl; + } + } + + friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& { + parser.writeToStream( os ); + return os; + } + + auto validate() const -> Result override { + for( auto const &opt : m_options ) { + auto result = opt.validate(); + if( !result ) + return result; + } + for( auto const &arg : m_args ) { + auto result = arg.validate(); + if( !result ) + return result; + } + return Result::ok(); + } + + using ParserBase::parse; + + auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override { + + struct ParserInfo { + ParserBase const* parser = nullptr; + size_t count = 0; + }; + const size_t totalParsers = m_options.size() + m_args.size(); + assert( totalParsers < 512 ); + // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do + ParserInfo parseInfos[512]; + + { + size_t i = 0; + for (auto const &opt : m_options) parseInfos[i++].parser = &opt; + for (auto const &arg : m_args) parseInfos[i++].parser = &arg; + } + + m_exeName.set( exeName ); + + auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); + while( result.value().remainingTokens() ) { + bool tokenParsed = false; + + for( size_t i = 0; i < totalParsers; ++i ) { + auto& parseInfo = parseInfos[i]; + if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) { + result = parseInfo.parser->parse(exeName, result.value().remainingTokens()); + if (!result) + return result; + if (result.value().type() != ParseResultType::NoMatch) { + tokenParsed = true; + ++parseInfo.count; + break; + } + } + } + + if( result.value().type() == ParseResultType::ShortCircuitAll ) + return result; + if( !tokenParsed ) + return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token ); + } + // !TBD Check missing required options + return result; + } + }; + + template<typename DerivedT> + template<typename T> + auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser { + return Parser() | static_cast<DerivedT const &>( *this ) | other; + } +} // namespace detail + +// A Combined parser +using detail::Parser; + +// A parser for options +using detail::Opt; + +// A parser for arguments +using detail::Arg; + +// Wrapper for argc, argv from main() +using detail::Args; + +// Specifies the name of the executable +using detail::ExeName; + +// Convenience wrapper for option parser that specifies the help option +using detail::Help; + +// enum of result types from a parse +using detail::ParseResultType; + +// Result type for parser operation +using detail::ParserResult; + +}} // namespace Catch::clara + +// end clara.hpp +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +// end catch_clara.h +namespace Catch { + + clara::Parser makeCommandLineParser( ConfigData& config ); + +} // end namespace Catch + +// end catch_commandline.h +#include <fstream> +#include <ctime> + +namespace Catch { + + clara::Parser makeCommandLineParser( ConfigData& config ) { + + using namespace clara; + + auto const setWarning = [&]( std::string const& warning ) { + auto warningSet = [&]() { + if( warning == "NoAssertions" ) + return WarnAbout::NoAssertions; + + if ( warning == "NoTests" ) + return WarnAbout::NoTests; + + return WarnAbout::Nothing; + }(); + + if (warningSet == WarnAbout::Nothing) + return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" ); + config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const loadTestNamesFromFile = [&]( std::string const& filename ) { + std::ifstream f( filename.c_str() ); + if( !f.is_open() ) + return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) + line = '"' + line + '"'; + config.testsOrTags.push_back( line + ',' ); + } + } + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setTestOrder = [&]( std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setRngSeed = [&]( std::string const& seed ) { + if( seed != "time" ) + return clara::detail::convertInto( seed, config.rngSeed ); + config.rngSeed = static_cast<unsigned int>( std::time(nullptr) ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setColourUsage = [&]( std::string const& useColour ) { + auto mode = toLower( useColour ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setWaitForKeypress = [&]( std::string const& keypress ) { + auto keypressLc = toLower( keypress ); + if( keypressLc == "start" ) + config.waitForKeypress = WaitForKeypress::BeforeStart; + else if( keypressLc == "exit" ) + config.waitForKeypress = WaitForKeypress::BeforeExit; + else if( keypressLc == "both" ) + config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; + else + return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setVerbosity = [&]( std::string const& verbosity ) { + auto lcVerbosity = toLower( verbosity ); + if( lcVerbosity == "quiet" ) + config.verbosity = Verbosity::Quiet; + else if( lcVerbosity == "normal" ) + config.verbosity = Verbosity::Normal; + else if( lcVerbosity == "high" ) + config.verbosity = Verbosity::High; + else + return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + + auto cli + = ExeName( config.processName ) + | Help( config.showHelp ) + | Opt( config.listTests ) + ["-l"]["--list-tests"] + ( "list all/matching test cases" ) + | Opt( config.listTags ) + ["-t"]["--list-tags"] + ( "list all/matching tags" ) + | Opt( config.showSuccessfulTests ) + ["-s"]["--success"] + ( "include successful tests in output" ) + | Opt( config.shouldDebugBreak ) + ["-b"]["--break"] + ( "break into debugger on failure" ) + | Opt( config.noThrow ) + ["-e"]["--nothrow"] + ( "skip exception tests" ) + | Opt( config.showInvisibles ) + ["-i"]["--invisibles"] + ( "show invisibles (tabs, newlines)" ) + | Opt( config.outputFilename, "filename" ) + ["-o"]["--out"] + ( "output filename" ) + | Opt( config.reporterNames, "name" ) + ["-r"]["--reporter"] + ( "reporter to use (defaults to console)" ) + | Opt( config.name, "name" ) + ["-n"]["--name"] + ( "suite name" ) + | Opt( [&]( bool ){ config.abortAfter = 1; } ) + ["-a"]["--abort"] + ( "abort at first failure" ) + | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" ) + ["-x"]["--abortx"] + ( "abort after x failures" ) + | Opt( setWarning, "warning name" ) + ["-w"]["--warn"] + ( "enable warnings" ) + | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) + ["-d"]["--durations"] + ( "show test durations" ) + | Opt( loadTestNamesFromFile, "filename" ) + ["-f"]["--input-file"] + ( "load test names to run from a file" ) + | Opt( config.filenamesAsTags ) + ["-#"]["--filenames-as-tags"] + ( "adds a tag for the filename" ) + | Opt( config.sectionsToRun, "section name" ) + ["-c"]["--section"] + ( "specify section to run" ) + | Opt( setVerbosity, "quiet|normal|high" ) + ["-v"]["--verbosity"] + ( "set output verbosity" ) + | Opt( config.listTestNamesOnly ) + ["--list-test-names-only"] + ( "list all/matching test cases names only" ) + | Opt( config.listReporters ) + ["--list-reporters"] + ( "list all reporters" ) + | Opt( setTestOrder, "decl|lex|rand" ) + ["--order"] + ( "test case order (defaults to decl)" ) + | Opt( setRngSeed, "'time'|number" ) + ["--rng-seed"] + ( "set a specific seed for random numbers" ) + | Opt( setColourUsage, "yes|no" ) + ["--use-colour"] + ( "should output be colourised" ) + | Opt( config.libIdentify ) + ["--libidentify"] + ( "report name and version according to libidentify standard" ) + | Opt( setWaitForKeypress, "start|exit|both" ) + ["--wait-for-keypress"] + ( "waits for a keypress before exiting" ) + | Opt( config.benchmarkResolutionMultiple, "multiplier" ) + ["--benchmark-resolution-multiple"] + ( "multiple of clock resolution to run benchmarks" ) + + | Arg( config.testsOrTags, "test name|pattern|tags" ) + ( "which test or tests to use" ); + + return cli; + } + +} // end namespace Catch +// end catch_commandline.cpp +// start catch_common.cpp + +#include <cstring> +#include <ostream> + +namespace Catch { + + bool SourceLineInfo::empty() const noexcept { + return file[0] == '\0'; + } + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept { + return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; + } + + std::string StreamEndStop::operator+() const { + return std::string(); + } + + NonCopyable::NonCopyable() = default; + NonCopyable::~NonCopyable() = default; + +} +// end catch_common.cpp +// start catch_config.cpp + +// start catch_enforce.h + +#include <stdexcept> + +#define CATCH_PREPARE_EXCEPTION( type, msg ) \ + type( ( Catch::ReusableStringStream() << msg ).str() ) +#define CATCH_INTERNAL_ERROR( msg ) \ + throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg); +#define CATCH_ERROR( msg ) \ + throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg ) +#define CATCH_ENFORCE( condition, msg ) \ + do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false) + +// end catch_enforce.h +namespace Catch { + + Config::Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + TestSpecParser parser(ITagAliasRegistry::get()); + if (data.testsOrTags.empty()) { + parser.parse("~[.]"); // All not hidden tests + } + else { + m_hasTestFilters = true; + for( auto const& testOrTags : data.testsOrTags ) + parser.parse( testOrTags ); + } + m_testSpec = parser.testSpec(); + } + + std::string const& Config::getFilename() const { + return m_data.outputFilename ; + } + + bool Config::listTests() const { return m_data.listTests; } + bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool Config::listTags() const { return m_data.listTags; } + bool Config::listReporters() const { return m_data.listReporters; } + + std::string Config::getProcessName() const { return m_data.processName; } + + std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; } + std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; } + std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } + + TestSpec const& Config::testSpec() const { return m_testSpec; } + bool Config::hasTestFilters() const { return m_hasTestFilters; } + + bool Config::showHelp() const { return m_data.showHelp; } + + // IConfig interface + bool Config::allowThrows() const { return !m_data.noThrow; } + std::ostream& Config::stream() const { return m_stream->stream(); } + std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } + bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; } + bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } + bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } + ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } + RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } + unsigned int Config::rngSeed() const { return m_data.rngSeed; } + int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; } + UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } + bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; } + int Config::abortAfter() const { return m_data.abortAfter; } + bool Config::showInvisibles() const { return m_data.showInvisibles; } + Verbosity Config::verbosity() const { return m_data.verbosity; } + + IStream const* Config::openStream() { + return Catch::makeStream(m_data.outputFilename); + } + +} // end namespace Catch +// end catch_config.cpp +// start catch_console_colour.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +// start catch_errno_guard.h + +namespace Catch { + + class ErrnoGuard { + public: + ErrnoGuard(); + ~ErrnoGuard(); + private: + int m_oldErrno; + }; + +} + +// end catch_errno_guard.h +#include <sstream> + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() = default; + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + virtual void use( Colour::Code _colourCode ) override { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN ); + + case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); + + default: + CATCH_ERROR( "Unknown colour requested" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = UseColour::Yes; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include <unistd.h> + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + virtual void use( Colour::Code _colourCode ) override { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0;34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + case Colour::BrightYellow: return setColour( "[1;33m" ); + + case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); + default: CATCH_INTERNAL_ERROR( "Unknown colour requested" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + Catch::cout() << '\033' << _escapeCode; + } + }; + + bool useColourOnPlatform() { + return +#ifdef CATCH_PLATFORM_MAC + !isDebuggerActive() && +#endif +#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) + isatty(STDOUT_FILENO) +#else + false +#endif + ; + } + IColourImpl* platformColourInstance() { + ErrnoGuard guard; + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = useColourOnPlatform() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) { use( _colourCode ); } + Colour::Colour( Colour&& rhs ) noexcept { + m_moved = rhs.m_moved; + rhs.m_moved = true; + } + Colour& Colour::operator=( Colour&& rhs ) noexcept { + m_moved = rhs.m_moved; + rhs.m_moved = true; + return *this; + } + + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + impl->use( _colourCode ); + } + + std::ostream& operator << ( std::ostream& os, Colour const& ) { + return os; + } + +} // end namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +// end catch_console_colour.cpp +// start catch_context.cpp + +namespace Catch { + + class Context : public IMutableContext, NonCopyable { + + public: // IContext + virtual IResultCapture* getResultCapture() override { + return m_resultCapture; + } + virtual IRunner* getRunner() override { + return m_runner; + } + + virtual IConfigPtr const& getConfig() const override { + return m_config; + } + + virtual ~Context() override; + + public: // IMutableContext + virtual void setResultCapture( IResultCapture* resultCapture ) override { + m_resultCapture = resultCapture; + } + virtual void setRunner( IRunner* runner ) override { + m_runner = runner; + } + virtual void setConfig( IConfigPtr const& config ) override { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IConfigPtr m_config; + IRunner* m_runner = nullptr; + IResultCapture* m_resultCapture = nullptr; + }; + + IMutableContext *IMutableContext::currentContext = nullptr; + + void IMutableContext::createContext() + { + currentContext = new Context(); + } + + void cleanUpContext() { + delete IMutableContext::currentContext; + IMutableContext::currentContext = nullptr; + } + IContext::~IContext() = default; + IMutableContext::~IMutableContext() = default; + Context::~Context() = default; +} +// end catch_context.cpp +// start catch_debug_console.cpp + +// start catch_debug_console.h + +#include <string> + +namespace Catch { + void writeToDebugConsole( std::string const& text ); +} + +// end catch_debug_console.h +#ifdef CATCH_PLATFORM_WINDOWS + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } + +#else + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } + +#endif // Platform +// end catch_debug_console.cpp +// start catch_debugger.cpp + +#ifdef CATCH_PLATFORM_MAC + +# include <assert.h> +# include <stdbool.h> +# include <sys/types.h> +# include <unistd.h> +# include <sys/sysctl.h> +# include <cstddef> +# include <ostream> + +namespace Catch { + + // The following function is taken directly from the following technical note: + // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + + int mib[4]; + struct kinfo_proc info; + std::size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + } // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) + #include <fstream> + #include <string> + + namespace Catch{ + // The standard POSIX way of detecting a debugger is to attempt to + // ptrace() the process, but this needs to be done from a child and not + // this process itself to still allow attaching to this process later + // if wanted, so is rather heavy. Under Linux we have the PID of the + // "debugger" (which doesn't need to be gdb, of course, it could also + // be strace, for example) in /proc/$PID/status, so just get it from + // there instead. + bool isDebuggerActive(){ + // Libstdc++ has a bug, where std::ifstream sets errno to 0 + // This way our users can properly assert over errno values + ErrnoGuard guard; + std::ifstream in("/proc/self/status"); + for( std::string line; std::getline(in, line); ) { + static const int PREFIX_LEN = 11; + if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; + } + } // namespace Catch +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + bool isDebuggerActive() { return false; } + } +#endif // Platform +// end catch_debugger.cpp +// start catch_decomposer.cpp + +namespace Catch { + + ITransientExpression::~ITransientExpression() = default; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { + if( lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ) + os << lhs << " " << op << " " << rhs; + else + os << lhs << "\n" << op << "\n" << rhs; + } +} +// end catch_decomposer.cpp +// start catch_errno_guard.cpp + +#include <cerrno> + +namespace Catch { + ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} + ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } +} +// end catch_errno_guard.cpp +// start catch_exception_translator_registry.cpp + +// start catch_exception_translator_registry.h + +#include <vector> +#include <string> +#include <memory> + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry(); + virtual void registerTranslator( const IExceptionTranslator* translator ); + virtual std::string translateActiveException() const override; + std::string tryTranslators() const; + + private: + std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators; + }; +} + +// end catch_exception_translator_registry.h +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { + } + + void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) ); + } + + std::string ExceptionTranslatorRegistry::translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::Detail::stringify( [exception description] ); + } +#else + // Compiling a mixed mode project with MSVC means that CLR + // exceptions will be caught in (...) as well. However, these + // do not fill-in std::current_exception and thus lead to crash + // when attempting rethrow. + // /EHa switch also causes structured exceptions to be caught + // here, but they fill-in current_exception properly, so + // at worst the output should be a little weird, instead of + // causing a crash. + if (std::current_exception() == nullptr) { + return "Non C++ exception. Possibly a CLR exception."; + } + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + std::rethrow_exception(std::current_exception()); + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string ExceptionTranslatorRegistry::tryTranslators() const { + if( m_translators.empty() ) + std::rethrow_exception(std::current_exception()); + else + return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); + } +} +// end catch_exception_translator_registry.cpp +// start catch_fatal_condition.cpp + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace { + // Report the error condition + void reportFatal( char const * const message ) { + Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); + } +} + +#endif // signals/SEH handling + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + struct SignalDefs { DWORD id; const char* name; }; + + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + static SignalDefs signalDefs[] = { + { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, + { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, + { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, + { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, + }; + + LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (auto const& def : signalDefs) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { + reportFatal(def.name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; + } + + FatalConditionHandler::FatalConditionHandler() { + isSet = true; + // 32k seems enough for Catch to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + exceptionHandlerHandle = nullptr; + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); + } + + void FatalConditionHandler::reset() { + if (isSet) { + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetThreadStackGuarantee(&guaranteeSize); + exceptionHandlerHandle = nullptr; + isSet = false; + } + } + + FatalConditionHandler::~FatalConditionHandler() { + reset(); + } + +bool FatalConditionHandler::isSet = false; +ULONG FatalConditionHandler::guaranteeSize = 0; +PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; + +} // namespace Catch + +#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace Catch { + + struct SignalDefs { + int id; + const char* name; + }; + static SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + + void FatalConditionHandler::handleSignal( int sig ) { + char const * name = "<unknown signal>"; + for (auto const& def : signalDefs) { + if (sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise( sig ); + } + + FatalConditionHandler::FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = SIGSTKSZ; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { }; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + + FatalConditionHandler::~FatalConditionHandler() { + reset(); + } + + void FatalConditionHandler::reset() { + if( isSet ) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + isSet = false; + } + } + + bool FatalConditionHandler::isSet = false; + struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; + +} // namespace Catch + +#else + +namespace Catch { + void FatalConditionHandler::reset() {} +} + +#endif // signals/SEH handling + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif +// end catch_fatal_condition.cpp +// start catch_interfaces_capture.cpp + +namespace Catch { + IResultCapture::~IResultCapture() = default; +} +// end catch_interfaces_capture.cpp +// start catch_interfaces_config.cpp + +namespace Catch { + IConfig::~IConfig() = default; +} +// end catch_interfaces_config.cpp +// start catch_interfaces_exception.cpp + +namespace Catch { + IExceptionTranslator::~IExceptionTranslator() = default; + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; +} +// end catch_interfaces_exception.cpp +// start catch_interfaces_registry_hub.cpp + +namespace Catch { + IRegistryHub::~IRegistryHub() = default; + IMutableRegistryHub::~IMutableRegistryHub() = default; +} +// end catch_interfaces_registry_hub.cpp +// start catch_interfaces_reporter.cpp + +// start catch_reporter_multi.h + +namespace Catch { + + class MultipleReporters : public IStreamingReporter { + using Reporters = std::vector<IStreamingReporterPtr>; + Reporters m_reporters; + + public: + void add( IStreamingReporterPtr&& reporter ); + + public: // IStreamingReporter + + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases( std::string const& spec ) override; + + static std::set<Verbosity> getSupportedVerbosities(); + + void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override; + void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override; + + void testRunStarting( TestRunInfo const& testRunInfo ) override; + void testGroupStarting( GroupInfo const& groupInfo ) override; + void testCaseStarting( TestCaseInfo const& testInfo ) override; + void sectionStarting( SectionInfo const& sectionInfo ) override; + void assertionStarting( AssertionInfo const& assertionInfo ) override; + + // The return value indicates if the messages buffer should be cleared: + bool assertionEnded( AssertionStats const& assertionStats ) override; + void sectionEnded( SectionStats const& sectionStats ) override; + void testCaseEnded( TestCaseStats const& testCaseStats ) override; + void testGroupEnded( TestGroupStats const& testGroupStats ) override; + void testRunEnded( TestRunStats const& testRunStats ) override; + + void skipTest( TestCaseInfo const& testInfo ) override; + bool isMulti() const override; + + }; + +} // end namespace Catch + +// end catch_reporter_multi.h +namespace Catch { + + ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& ReporterConfig::stream() const { return *m_stream; } + IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; } + + TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {} + + GroupInfo::GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + AssertionStats::AssertionStats( AssertionResult const& _assertionResult, + std::vector<MessageInfo> const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression; + + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + + AssertionStats::~AssertionStats() = default; + + SectionStats::SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + + SectionStats::~SectionStats() = default; + + TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + + TestCaseStats::~TestCaseStats() = default; + + TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + + TestGroupStats::~TestGroupStats() = default; + + TestRunStats::TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + TestRunStats::~TestRunStats() = default; + + void IStreamingReporter::fatalErrorEncountered( StringRef ) {} + bool IStreamingReporter::isMulti() const { return false; } + + IReporterFactory::~IReporterFactory() = default; + IReporterRegistry::~IReporterRegistry() = default; + + void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) { + + if( !existingReporter ) { + existingReporter = std::move( additionalReporter ); + return; + } + + MultipleReporters* multi = nullptr; + + if( existingReporter->isMulti() ) { + multi = static_cast<MultipleReporters*>( existingReporter.get() ); + } + else { + auto newMulti = std::unique_ptr<MultipleReporters>( new MultipleReporters ); + newMulti->add( std::move( existingReporter ) ); + multi = newMulti.get(); + existingReporter = std::move( newMulti ); + } + multi->add( std::move( additionalReporter ) ); + } + +} // end namespace Catch +// end catch_interfaces_reporter.cpp +// start catch_interfaces_runner.cpp + +namespace Catch { + IRunner::~IRunner() = default; +} +// end catch_interfaces_runner.cpp +// start catch_interfaces_testcase.cpp + +namespace Catch { + ITestInvoker::~ITestInvoker() = default; + ITestCaseRegistry::~ITestCaseRegistry() = default; +} +// end catch_interfaces_testcase.cpp +// start catch_leak_detector.cpp + +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include <crtdbg.h> + +namespace Catch { + + LeakDetector::LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +} + +#else + + Catch::LeakDetector::LeakDetector() {} + +#endif +// end catch_leak_detector.cpp +// start catch_list.cpp + +// start catch_list.h + +#include <set> + +namespace Catch { + + std::size_t listTests( Config const& config ); + + std::size_t listTestsNamesOnly( Config const& config ); + + struct TagInfo { + void add( std::string const& spelling ); + std::string all() const; + + std::set<std::string> spellings; + std::size_t count = 0; + }; + + std::size_t listTags( Config const& config ); + + std::size_t listReporters( Config const& /*config*/ ); + + Option<std::size_t> list( Config const& config ); + +} // end namespace Catch + +// end catch_list.h +// start catch_text.h + +namespace Catch { + using namespace clara::TextFlow; +} + +// end catch_text.h +#include <limits> +#include <algorithm> +#include <iomanip> + +namespace Catch { + + std::size_t listTests( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.hasTestFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + } + + auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCaseInfo : matchedTestCases ) { + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n"; + if( config.verbosity() >= Verbosity::High ) { + Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl; + std::string description = testCaseInfo.description; + if( description.empty() ) + description = "(NO DESCRIPTION)"; + Catch::cout() << Column( description ).indent(4) << std::endl; + } + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n"; + } + + if( !config.hasTestFilters() ) + Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl; + else + Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl; + return matchedTestCases.size(); + } + + std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec testSpec = config.testSpec(); + std::size_t matchedTests = 0; + std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCaseInfo : matchedTestCases ) { + matchedTests++; + if( startsWith( testCaseInfo.name, '#' ) ) + Catch::cout() << '"' << testCaseInfo.name << '"'; + else + Catch::cout() << testCaseInfo.name; + if ( config.verbosity() >= Verbosity::High ) + Catch::cout() << "\t@" << testCaseInfo.lineInfo; + Catch::cout() << std::endl; + } + return matchedTests; + } + + void TagInfo::add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + + std::string TagInfo::all() const { + std::string out; + for( auto const& spelling : spellings ) + out += "[" + spelling + "]"; + return out; + } + + std::size_t listTags( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.hasTestFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + } + + std::map<std::string, TagInfo> tagCounts; + + std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCase : matchedTestCases ) { + for( auto const& tagName : testCase.getTestCaseInfo().tags ) { + std::string lcaseTagName = toLower( tagName ); + auto countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( auto const& tagCount : tagCounts ) { + ReusableStringStream rss; + rss << " " << std::setw(2) << tagCount.second.count << " "; + auto str = rss.str(); + auto wrapper = Column( tagCount.second.all() ) + .initialIndent( 0 ) + .indent( str.size() ) + .width( CATCH_CONFIG_CONSOLE_WIDTH-10 ); + Catch::cout() << str << wrapper << '\n'; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; + return tagCounts.size(); + } + + std::size_t listReporters( Config const& /*config*/ ) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + std::size_t maxNameLen = 0; + for( auto const& factoryKvp : factories ) + maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() ); + + for( auto const& factoryKvp : factories ) { + Catch::cout() + << Column( factoryKvp.first + ":" ) + .indent(2) + .width( 5+maxNameLen ) + + Column( factoryKvp.second->getDescription() ) + .initialIndent(0) + .indent(2) + .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) + << "\n"; + } + Catch::cout() << std::endl; + return factories.size(); + } + + Option<std::size_t> list( Config const& config ) { + Option<std::size_t> listedCount; + if( config.listTests() ) + listedCount = listedCount.valueOr(0) + listTests( config ); + if( config.listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); + if( config.listTags() ) + listedCount = listedCount.valueOr(0) + listTags( config ); + if( config.listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters( config ); + return listedCount; + } + +} // end namespace Catch +// end catch_list.cpp +// start catch_matchers.cpp + +namespace Catch { +namespace Matchers { + namespace Impl { + + std::string MatcherUntypedBase::toString() const { + if( m_cachedToString.empty() ) + m_cachedToString = describe(); + return m_cachedToString; + } + + MatcherUntypedBase::~MatcherUntypedBase() = default; + + } // namespace Impl +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch +// end catch_matchers.cpp +// start catch_matchers_floating.cpp + +#include <cstdlib> +#include <cstdint> +#include <cstring> +#include <stdexcept> + +namespace Catch { +namespace Matchers { +namespace Floating { +enum class FloatingPointKind : uint8_t { + Float, + Double +}; +} +} +} + +namespace { + +template <typename T> +struct Converter; + +template <> +struct Converter<float> { + static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated"); + Converter(float f) { + std::memcpy(&i, &f, sizeof(f)); + } + int32_t i; +}; + +template <> +struct Converter<double> { + static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated"); + Converter(double d) { + std::memcpy(&i, &d, sizeof(d)); + } + int64_t i; +}; + +template <typename T> +auto convert(T t) -> Converter<T> { + return Converter<T>(t); +} + +template <typename FP> +bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) { + // Comparison with NaN should always be false. + // This way we can rule it out before getting into the ugly details + if (std::isnan(lhs) || std::isnan(rhs)) { + return false; + } + + auto lc = convert(lhs); + auto rc = convert(rhs); + + if ((lc.i < 0) != (rc.i < 0)) { + // Potentially we can have +0 and -0 + return lhs == rhs; + } + + auto ulpDiff = std::abs(lc.i - rc.i); + return ulpDiff <= maxUlpDiff; +} + +} + +namespace Catch { +namespace Matchers { +namespace Floating { + WithinAbsMatcher::WithinAbsMatcher(double target, double margin) + :m_target{ target }, m_margin{ margin } { + if (m_margin < 0) { + throw std::domain_error("Allowed margin difference has to be >= 0"); + } + } + + // Performs equivalent check of std::fabs(lhs - rhs) <= margin + // But without the subtraction to allow for INFINITY in comparison + bool WithinAbsMatcher::match(double const& matchee) const { + return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee); + } + + std::string WithinAbsMatcher::describe() const { + return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target); + } + + WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType) + :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } { + if (m_ulps < 0) { + throw std::domain_error("Allowed ulp difference has to be >= 0"); + } + } + + bool WithinUlpsMatcher::match(double const& matchee) const { + switch (m_type) { + case FloatingPointKind::Float: + return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps); + case FloatingPointKind::Double: + return almostEqualUlps<double>(matchee, m_target, m_ulps); + default: + throw std::domain_error("Unknown FloatingPointKind value"); + } + } + + std::string WithinUlpsMatcher::describe() const { + return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); + } + +}// namespace Floating + +Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double); +} + +Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float); +} + +Floating::WithinAbsMatcher WithinAbs(double target, double margin) { + return Floating::WithinAbsMatcher(target, margin); +} + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.cpp +// start catch_matchers_generic.cpp + +std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) { + if (desc.empty()) { + return "matches undescribed predicate"; + } else { + return "matches predicate: \"" + desc + '"'; + } +} +// end catch_matchers_generic.cpp +// start catch_matchers_string.cpp + +#include <regex> + +namespace Catch { +namespace Matchers { + + namespace StdString { + + CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string CasedString::adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + } + std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : std::string(); + } + + StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) + : m_comparator( comparator ), + m_operation( operation ) { + } + + std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; + } + + EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} + + bool EqualsMatcher::match( std::string const& source ) const { + return m_comparator.adjustString( source ) == m_comparator.m_str; + } + + ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} + + bool ContainsMatcher::match( std::string const& source ) const { + return contains( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} + + bool StartsWithMatcher::match( std::string const& source ) const { + return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} + + bool EndsWithMatcher::match( std::string const& source ) const { + return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {} + + bool RegexMatcher::match(std::string const& matchee) const { + auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway + if (m_caseSensitivity == CaseSensitive::Choice::No) { + flags |= std::regex::icase; + } + auto reg = std::regex(m_regex, flags); + return std::regex_match(matchee, reg); + } + + std::string RegexMatcher::describe() const { + return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively"); + } + + } // namespace StdString + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + + StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) { + return StdString::RegexMatcher(regex, caseSensitivity); + } + +} // namespace Matchers +} // namespace Catch +// end catch_matchers_string.cpp +// start catch_message.cpp + +// start catch_uncaught_exceptions.h + +namespace Catch { + bool uncaught_exceptions(); +} // end namespace Catch + +// end catch_uncaught_exceptions.h +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + bool MessageInfo::operator==( MessageInfo const& other ) const { + return sequence == other.sequence; + } + + bool MessageInfo::operator<( MessageInfo const& other ) const { + return sequence < other.sequence; + } + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + Catch::MessageBuilder::MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + :m_info(macroName, lineInfo, type) {} + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ) + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + + ScopedMessage::~ScopedMessage() { + if ( !uncaught_exceptions() ){ + getResultCapture().popScopedMessage(m_info); + } + } +} // end namespace Catch +// end catch_message.cpp +// start catch_random_number_generator.cpp + +// start catch_random_number_generator.h + +#include <algorithm> + +namespace Catch { + + struct IConfig; + + void seedRng( IConfig const& config ); + + unsigned int rngSeed(); + + struct RandomNumberGenerator { + using result_type = unsigned int; + + static constexpr result_type (min)() { return 0; } + static constexpr result_type (max)() { return 1000000; } + + result_type operator()( result_type n ) const; + result_type operator()() const; + + template<typename V> + static void shuffle( V& vector ) { + RandomNumberGenerator rng; + std::shuffle( vector.begin(), vector.end(), rng ); + } + }; + +} + +// end catch_random_number_generator.h +#include <cstdlib> + +namespace Catch { + + void seedRng( IConfig const& config ) { + if( config.rngSeed() != 0 ) + std::srand( config.rngSeed() ); + } + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + + RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const { + return std::rand() % n; + } + RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const { + return std::rand() % (max)(); + } + +} +// end catch_random_number_generator.cpp +// start catch_registry_hub.cpp + +// start catch_test_case_registry_impl.h + +#include <vector> +#include <set> +#include <algorithm> +#include <ios> + +namespace Catch { + + class TestCase; + struct IConfig; + + std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + + void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ); + + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ); + + class TestRegistry : public ITestCaseRegistry { + public: + virtual ~TestRegistry() = default; + + virtual void registerTest( TestCase const& testCase ); + + std::vector<TestCase> const& getAllTests() const override; + std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override; + + private: + std::vector<TestCase> m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder; + mutable std::vector<TestCase> m_sortedFunctions; + std::size_t m_unnamedCount = 0; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class TestInvokerAsFunction : public ITestInvoker { + void(*m_testAsFunction)(); + public: + TestInvokerAsFunction( void(*testAsFunction)() ) noexcept; + + void invoke() const override; + }; + + std::string extractClassName( StringRef const& classOrQualifiedMethodName ); + + /////////////////////////////////////////////////////////////////////////// + +} // end namespace Catch + +// end catch_test_case_registry_impl.h +// start catch_reporter_registry.h + +#include <map> + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + ~ReporterRegistry() override; + + IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override; + + void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ); + void registerListener( IReporterFactoryPtr const& factory ); + + FactoryMap const& getFactories() const override; + Listeners const& getListeners() const override; + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +// end catch_reporter_registry.h +// start catch_tag_alias_registry.h + +// start catch_tag_alias.h + +#include <string> + +namespace Catch { + + struct TagAlias { + TagAlias(std::string const& _tag, SourceLineInfo _lineInfo); + + std::string tag; + SourceLineInfo lineInfo; + }; + +} // end namespace Catch + +// end catch_tag_alias.h +#include <map> + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + ~TagAliasRegistry() override; + TagAlias const* find( std::string const& alias ) const override; + std::string expandAliases( std::string const& unexpandedTestSpec ) const override; + void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); + + private: + std::map<std::string, TagAlias> m_registry; + }; + +} // end namespace Catch + +// end catch_tag_alias_registry.h +// start catch_startup_exception_registry.h + +#include <vector> +#include <exception> + +namespace Catch { + + class StartupExceptionRegistry { + public: + void add(std::exception_ptr const& exception) noexcept; + std::vector<std::exception_ptr> const& getExceptions() const noexcept; + private: + std::vector<std::exception_ptr> m_exceptions; + }; + +} // end namespace Catch + +// end catch_startup_exception_registry.h +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub, + private NonCopyable { + + public: // IRegistryHub + RegistryHub() = default; + IReporterRegistry const& getReporterRegistry() const override { + return m_reporterRegistry; + } + ITestCaseRegistry const& getTestCaseRegistry() const override { + return m_testCaseRegistry; + } + IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override { + return m_exceptionTranslatorRegistry; + } + ITagAliasRegistry const& getTagAliasRegistry() const override { + return m_tagAliasRegistry; + } + StartupExceptionRegistry const& getStartupExceptionRegistry() const override { + return m_exceptionRegistry; + } + + public: // IMutableRegistryHub + void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override { + m_reporterRegistry.registerReporter( name, factory ); + } + void registerListener( IReporterFactoryPtr const& factory ) override { + m_reporterRegistry.registerListener( factory ); + } + void registerTest( TestCase const& testInfo ) override { + m_testCaseRegistry.registerTest( testInfo ); + } + void registerTranslator( const IExceptionTranslator* translator ) override { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override { + m_tagAliasRegistry.add( alias, tag, lineInfo ); + } + void registerStartupException() noexcept override { + m_exceptionRegistry.add(std::current_exception()); + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + TagAliasRegistry m_tagAliasRegistry; + StartupExceptionRegistry m_exceptionRegistry; + }; + + // Single, global, instance + RegistryHub*& getTheRegistryHub() { + static RegistryHub* theRegistryHub = nullptr; + if( !theRegistryHub ) + theRegistryHub = new RegistryHub(); + return theRegistryHub; + } + } + + IRegistryHub& getRegistryHub() { + return *getTheRegistryHub(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return *getTheRegistryHub(); + } + void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = nullptr; + cleanUpContext(); + ReusableStringStream::cleanup(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + +} // end namespace Catch +// end catch_registry_hub.cpp +// start catch_reporter_registry.cpp + +namespace Catch { + + ReporterRegistry::~ReporterRegistry() = default; + + IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const { + auto it = m_factories.find( name ); + if( it == m_factories.end() ) + return nullptr; + return it->second->create( ReporterConfig( config ) ); + } + + void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) { + m_factories.emplace(name, factory); + } + void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) { + m_listeners.push_back( factory ); + } + + IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const { + return m_factories; + } + IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const { + return m_listeners; + } + +} +// end catch_reporter_registry.cpp +// start catch_result_type.cpp + +namespace Catch { + + bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); + } + + bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch +// end catch_result_type.cpp +// start catch_run_context.cpp + +#include <cassert> +#include <algorithm> +#include <sstream> + +namespace Catch { + + class RedirectedStream { + std::ostream& m_originalStream; + std::ostream& m_redirectionStream; + std::streambuf* m_prevBuf; + + public: + RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) + : m_originalStream( originalStream ), + m_redirectionStream( redirectionStream ), + m_prevBuf( m_originalStream.rdbuf() ) + { + m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); + } + ~RedirectedStream() { + m_originalStream.rdbuf( m_prevBuf ); + } + }; + + class RedirectedStdOut { + ReusableStringStream m_rss; + RedirectedStream m_cout; + public: + RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} + auto str() const -> std::string { return m_rss.str(); } + }; + + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes + class RedirectedStdErr { + ReusableStringStream m_rss; + RedirectedStream m_cerr; + RedirectedStream m_clog; + public: + RedirectedStdErr() + : m_cerr( Catch::cerr(), m_rss.get() ), + m_clog( Catch::clog(), m_rss.get() ) + {} + auto str() const -> std::string { return m_rss.str(); } + }; + + RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) + : m_runInfo(_config->name()), + m_context(getCurrentMutableContext()), + m_config(_config), + m_reporter(std::move(reporter)), + m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal }, + m_includeSuccessfulResults( m_config->includeSuccessfulResults() ) + { + m_context.setRunner(this); + m_context.setConfig(m_config); + m_context.setResultCapture(this); + m_reporter->testRunStarting(m_runInfo); + } + + RunContext::~RunContext() { + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting())); + } + + void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount)); + } + + void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting())); + } + + Totals RunContext::runTest(TestCase const& testCase) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + auto const& testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting(testInfo); + + m_activeTestCase = &testCase; + + ITracker& rootTracker = m_trackerContext.startRun(); + assert(rootTracker.isSectionTracker()); + static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun()); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); + runCurrentTest(redirectedCout, redirectedCerr); + } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting()); + + Totals deltaTotals = m_totals.delta(prevTotals); + if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded(TestCaseStats(testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting())); + + m_activeTestCase = nullptr; + m_testCaseTracker = nullptr; + + return deltaTotals; + } + + IConfigPtr RunContext::config() const { + return m_config; + } + + IStreamingReporter& RunContext::reporter() const { + return *m_reporter; + } + + void RunContext::assertionEnded(AssertionResult const & result) { + if (result.getResultType() == ResultWas::Ok) { + m_totals.assertions.passed++; + m_lastAssertionPassed = true; + } else if (!result.isOk()) { + m_lastAssertionPassed = false; + if( m_activeTestCase->getTestCaseInfo().okToFail() ) + m_totals.assertions.failedButOk++; + else + m_totals.assertions.failed++; + } + else { + m_lastAssertionPassed = true; + } + + // We have no use for the return value (whether messages should be cleared), because messages were made scoped + // and should be let to clear themselves out. + static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); + + // Reset working state + resetAssertionInfo(); + m_lastResult = result; + } + void RunContext::resetAssertionInfo() { + m_lastAssertionInfo.macroName = StringRef(); + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; + } + + bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { + ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); + if (!sectionTracker.isOpen()) + return false; + m_activeSections.push_back(§ionTracker); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting(sectionInfo); + + assertions = m_totals.assertions; + + return true; + } + + bool RunContext::testForMissingAssertions(Counts& assertions) { + if (assertions.total() != 0) + return false; + if (!m_config->warnAboutMissingAssertions()) + return false; + if (m_trackerContext.currentTracker().hasChildren()) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + void RunContext::sectionEnded(SectionEndInfo const & endInfo) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + if (!m_activeSections.empty()) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); + m_messages.clear(); + } + + void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { + if (m_unfinishedSections.empty()) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back(endInfo); + } + void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { + m_reporter->benchmarkStarting( info ); + } + void RunContext::benchmarkEnded( BenchmarkStats const& stats ) { + m_reporter->benchmarkEnded( stats ); + } + + void RunContext::pushScopedMessage(MessageInfo const & message) { + m_messages.push_back(message); + } + + void RunContext::popScopedMessage(MessageInfo const & message) { + m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); + } + + std::string RunContext::getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : std::string(); + } + + const AssertionResult * RunContext::getLastResult() const { + return &(*m_lastResult); + } + + void RunContext::exceptionEarlyReported() { + m_shouldReportUnexpected = false; + } + + void RunContext::handleFatalErrorCondition( StringRef message ) { + // First notify reporter that bad things happened + m_reporter->fatalErrorEncountered(message); + + // Don't rebuild the result -- the stringification itself can cause more fatal errors + // Instead, fake a result data. + AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); + tempResult.message = message; + AssertionResult result(m_lastAssertionInfo, tempResult); + + assertionEnded(result); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); + m_reporter->sectionEnded(testCaseSectionStats); + + auto const& testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + deltaTotals.assertions.failed = 1; + m_reporter->testCaseEnded(TestCaseStats(testInfo, + deltaTotals, + std::string(), + std::string(), + false)); + m_totals.testCases.failed++; + testGroupEnded(std::string(), m_totals, 1, 1); + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); + } + + bool RunContext::lastAssertionPassed() { + return m_lastAssertionPassed; + } + + void RunContext::assertionPassed() { + m_lastAssertionPassed = true; + ++m_totals.assertions.passed; + resetAssertionInfo(); + } + + bool RunContext::aborting() const { + return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter()); + } + + void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) { + auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); + m_reporter->sectionStarting(testCaseSection); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + m_shouldReportUnexpected = true; + m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal }; + + seedRng(*m_config); + + Timer timer; + try { + if (m_reporter->getPreferences().shouldRedirectStdOut) { + RedirectedStdOut redirectedStdOut; + RedirectedStdErr redirectedStdErr; + timer.start(); + invokeActiveTestCase(); + redirectedCout += redirectedStdOut.str(); + redirectedCerr += redirectedStdErr.str(); + + } else { + timer.start(); + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } catch (TestFailureException&) { + // This just means the test was aborted due to failure + } catch (...) { + // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions + // are reported without translation at the point of origin. + if( m_shouldReportUnexpected ) { + AssertionReaction dummyReaction; + handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction ); + } + } + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); + m_reporter->sectionEnded(testCaseSectionStats); + } + + void RunContext::invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); + } + + void RunContext::handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for (auto it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it) + sectionEnded(*it); + m_unfinishedSections.clear(); + } + + void RunContext::handleExpr( + AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction + ) { + m_reporter->assertionStarting( info ); + + bool negated = isFalseTest( info.resultDisposition ); + bool result = expr.getResult() != negated; + + if( result ) { + if (!m_includeSuccessfulResults) { + assertionPassed(); + } + else { + reportExpr(info, ResultWas::Ok, &expr, negated); + } + } + else { + reportExpr(info, ResultWas::ExpressionFailed, &expr, negated ); + populateReaction( reaction ); + } + } + void RunContext::reportExpr( + AssertionInfo const &info, + ResultWas::OfType resultType, + ITransientExpression const *expr, + bool negated ) { + + m_lastAssertionInfo = info; + AssertionResultData data( resultType, LazyExpression( negated ) ); + + AssertionResult assertionResult{ info, data }; + assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; + + assertionEnded( assertionResult ); + } + + void RunContext::handleMessage( + AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction + ) { + m_reporter->assertionStarting( info ); + + m_lastAssertionInfo = info; + + AssertionResultData data( resultType, LazyExpression( false ) ); + data.message = message; + AssertionResult assertionResult{ m_lastAssertionInfo, data }; + assertionEnded( assertionResult ); + if( !assertionResult.isOk() ) + populateReaction( reaction ); + } + void RunContext::handleUnexpectedExceptionNotThrown( + AssertionInfo const& info, + AssertionReaction& reaction + ) { + handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction); + } + + void RunContext::handleUnexpectedInflightException( + AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); + data.message = message; + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + populateReaction( reaction ); + } + + void RunContext::populateReaction( AssertionReaction& reaction ) { + reaction.shouldDebugBreak = m_config->shouldDebugBreak(); + reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal); + } + + void RunContext::handleIncomplete( + AssertionInfo const& info + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); + data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + } + void RunContext::handleNonExpr( + AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( resultType, LazyExpression( false ) ); + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + + if( !assertionResult.isOk() ) + populateReaction( reaction ); + } + + IResultCapture& getResultCapture() { + if (auto* capture = getCurrentContext().getResultCapture()) + return *capture; + else + CATCH_INTERNAL_ERROR("No result capture instance"); + } +} +// end catch_run_context.cpp +// start catch_section.cpp + +namespace Catch { + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); + if( uncaught_exceptions() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + +} // end namespace Catch +// end catch_section.cpp +// start catch_section_info.cpp + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description ) + : name( _name ), + description( _description ), + lineInfo( _lineInfo ) + {} + + SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) + : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) + {} + +} // end namespace Catch +// end catch_section_info.cpp +// start catch_session.cpp + +// start catch_session.h + +#include <memory> + +namespace Catch { + + class Session : NonCopyable { + public: + + Session(); + ~Session() override; + + void showHelp() const; + void libIdentify(); + + int applyCommandLine( int argc, char const * const * argv ); + + void useConfigData( ConfigData const& configData ); + + int run( int argc, char* argv[] ); + #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) + int run( int argc, wchar_t* const argv[] ); + #endif + int run(); + + clara::Parser const& cli() const; + void cli( clara::Parser const& newParser ); + ConfigData& configData(); + Config& config(); + private: + int runInternal(); + + clara::Parser m_cli; + ConfigData m_configData; + std::shared_ptr<Config> m_config; + bool m_startupExceptions = false; + }; + +} // end namespace Catch + +// end catch_session.h +// start catch_version.h + +#include <iosfwd> + +namespace Catch { + + // Versioning information + struct Version { + Version( Version const& ) = delete; + Version& operator=( Version const& ) = delete; + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + char const * const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + }; + + Version const& libraryVersion(); +} + +// end catch_version.h +#include <cstdlib> +#include <iomanip> + +namespace Catch { + + namespace { + const int MaxExitCode = 255; + + IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) { + auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config); + CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'"); + + return reporter; + } + +#ifndef CATCH_CONFIG_DEFAULT_REPORTER +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + + IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) { + auto const& reporterNames = config->getReporterNames(); + if (reporterNames.empty()) + return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config); + + IStreamingReporterPtr reporter; + for (auto const& name : reporterNames) + addReporter(reporter, createReporter(name, config)); + return reporter; + } + +#undef CATCH_CONFIG_DEFAULT_REPORTER + + void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) { + auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); + for (auto const& listener : listeners) + addReporter(reporters, listener->create(Catch::ReporterConfig(config))); + } + + Catch::Totals runTests(std::shared_ptr<Config> const& config) { + IStreamingReporterPtr reporter = makeReporter(config); + addListeners(reporter, config); + + RunContext context(config, std::move(reporter)); + + Totals totals; + + context.testGroupStarting(config->name(), 1, 1); + + TestSpec testSpec = config->testSpec(); + + auto const& allTestCases = getAllTestCasesSorted(*config); + for (auto const& testCase : allTestCases) { + if (!context.aborting() && matchTest(testCase, testSpec, *config)) + totals += context.runTest(testCase); + else + context.reporter().skipTest(testCase); + } + + if (config->warnAboutNoTests() && totals.testCases.total() == 0) { + ReusableStringStream testConfig; + + bool first = true; + for (const auto& input : config->getTestsOrTags()) { + if (!first) { testConfig << ' '; } + first = false; + testConfig << input; + } + + context.reporter().noMatchingTestCases(testConfig.str()); + totals.error = -1; + } + + context.testGroupEnded(config->name(), totals, 1, 1); + return totals; + } + + void applyFilenamesAsTags(Catch::IConfig const& config) { + auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config)); + for (auto& testCase : tests) { + auto tags = testCase.tags; + + std::string filename = testCase.lineInfo.file; + auto lastSlash = filename.find_last_of("\\/"); + if (lastSlash != std::string::npos) { + filename.erase(0, lastSlash); + filename[0] = '#'; + } + + auto lastDot = filename.find_last_of('.'); + if (lastDot != std::string::npos) { + filename.erase(lastDot); + } + + tags.push_back(std::move(filename)); + setTags(testCase, tags); + } + } + + } // anon namespace + + Session::Session() { + static bool alreadyInstantiated = false; + if( alreadyInstantiated ) { + try { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); } + catch(...) { getMutableRegistryHub().registerStartupException(); } + } + + const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions(); + if ( !exceptions.empty() ) { + m_startupExceptions = true; + Colour colourGuard( Colour::Red ); + Catch::cerr() << "Errors occurred during startup!" << '\n'; + // iterate over all exceptions and notify user + for ( const auto& ex_ptr : exceptions ) { + try { + std::rethrow_exception(ex_ptr); + } catch ( std::exception const& ex ) { + Catch::cerr() << Column( ex.what() ).indent(2) << '\n'; + } + } + } + + alreadyInstantiated = true; + m_cli = makeCommandLineParser( m_configData ); + } + Session::~Session() { + Catch::cleanUp(); + } + + void Session::showHelp() const { + Catch::cout() + << "\nCatch v" << libraryVersion() << "\n" + << m_cli << std::endl + << "For more detailed usage please see the project docs\n" << std::endl; + } + void Session::libIdentify() { + Catch::cout() + << std::left << std::setw(16) << "description: " << "A Catch test executable\n" + << std::left << std::setw(16) << "category: " << "testframework\n" + << std::left << std::setw(16) << "framework: " << "Catch Test\n" + << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; + } + + int Session::applyCommandLine( int argc, char const * const * argv ) { + if( m_startupExceptions ) + return 1; + + auto result = m_cli.parse( clara::Args( argc, argv ) ); + if( !result ) { + Catch::cerr() + << Colour( Colour::Red ) + << "\nError(s) in input:\n" + << Column( result.errorMessage() ).indent( 2 ) + << "\n\n"; + Catch::cerr() << "Run with -? for usage\n" << std::endl; + return MaxExitCode; + } + + if( m_configData.showHelp ) + showHelp(); + if( m_configData.libIdentify ) + libIdentify(); + m_config.reset(); + return 0; + } + + void Session::useConfigData( ConfigData const& configData ) { + m_configData = configData; + m_config.reset(); + } + + int Session::run( int argc, char* argv[] ) { + if( m_startupExceptions ) + return 1; + int returnCode = applyCommandLine( argc, argv ); + if( returnCode == 0 ) + returnCode = run(); + return returnCode; + } + +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) + int Session::run( int argc, wchar_t* const argv[] ) { + + char **utf8Argv = new char *[ argc ]; + + for ( int i = 0; i < argc; ++i ) { + int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); + + utf8Argv[ i ] = new char[ bufSize ]; + + WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); + } + + int returnCode = run( argc, utf8Argv ); + + for ( int i = 0; i < argc; ++i ) + delete [] utf8Argv[ i ]; + + delete [] utf8Argv; + + return returnCode; + } +#endif + int Session::run() { + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before starting" << std::endl; + static_cast<void>(std::getchar()); + } + int exitCode = runInternal(); + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; + static_cast<void>(std::getchar()); + } + return exitCode; + } + + clara::Parser const& Session::cli() const { + return m_cli; + } + void Session::cli( clara::Parser const& newParser ) { + m_cli = newParser; + } + ConfigData& Session::configData() { + return m_configData; + } + Config& Session::config() { + if( !m_config ) + m_config = std::make_shared<Config>( m_configData ); + return *m_config; + } + + int Session::runInternal() { + if( m_startupExceptions ) + return 1; + + if( m_configData.showHelp || m_configData.libIdentify ) + return 0; + + try + { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option<std::size_t> listed = list( config() ) ) + return static_cast<int>( *listed ); + + auto totals = runTests( m_config ); + // Note that on unices only the lower 8 bits are usually used, clamping + // the return value to 255 prevents false negative when some multiple + // of 256 tests has failed + return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed))); + } + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return MaxExitCode; + } + } + +} // end namespace Catch +// end catch_session.cpp +// start catch_startup_exception_registry.cpp + +namespace Catch { + void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { + try { + m_exceptions.push_back(exception); + } + catch(...) { + // If we run out of memory during start-up there's really not a lot more we can do about it + std::terminate(); + } + } + + std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept { + return m_exceptions; + } + +} // end namespace Catch +// end catch_startup_exception_registry.cpp +// start catch_stream.cpp + +#include <cstdio> +#include <iostream> +#include <fstream> +#include <sstream> +#include <vector> +#include <memory> + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { + + Catch::IStream::~IStream() = default; + + namespace detail { namespace { + template<typename WriterF, std::size_t bufferSize=256> + class StreamBufImpl : public std::streambuf { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() noexcept { + StreamBufImpl::sync(); + } + + private: + int overflow( int c ) override { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast<char>( c ) ) ); + else + sputc( static_cast<char>( c ) ); + } + return 0; + } + + int sync() override { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( StringRef filename ) { + m_ofs.open( filename.c_str() ); + CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" ); + } + ~FileStream() override = default; + public: // IStream + std::ostream& stream() const override { + return m_ofs; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream() : m_os( Catch::cout().rdbuf() ) {} + ~CoutStream() override = default; + + public: // IStream + std::ostream& stream() const override { return m_os; } + }; + + /////////////////////////////////////////////////////////////////////////// + + class DebugOutStream : public IStream { + std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream() + : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ), + m_os( m_streamBuf.get() ) + {} + + ~DebugOutStream() override = default; + + public: // IStream + std::ostream& stream() const override { return m_os; } + }; + + }} // namespace anon::detail + + /////////////////////////////////////////////////////////////////////////// + + auto makeStream( StringRef const &filename ) -> IStream const* { + if( filename.empty() ) + return new detail::CoutStream(); + else if( filename[0] == '%' ) { + if( filename == "%debug" ) + return new detail::DebugOutStream(); + else + CATCH_ERROR( "Unrecognised stream: '" << filename << "'" ); + } + else + return new detail::FileStream( filename ); + } + + // This class encapsulates the idea of a pool of ostringstreams that can be reused. + struct StringStreams { + std::vector<std::unique_ptr<std::ostringstream>> m_streams; + std::vector<std::size_t> m_unused; + std::ostringstream m_referenceStream; // Used for copy state/ flags from + static StringStreams* s_instance; + + auto add() -> std::size_t { + if( m_unused.empty() ) { + m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) ); + return m_streams.size()-1; + } + else { + auto index = m_unused.back(); + m_unused.pop_back(); + return index; + } + } + + void release( std::size_t index ) { + m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state + m_unused.push_back(index); + } + + // !TBD: put in TLS + static auto instance() -> StringStreams& { + if( !s_instance ) + s_instance = new StringStreams(); + return *s_instance; + } + static void cleanup() { + delete s_instance; + s_instance = nullptr; + } + }; + + StringStreams* StringStreams::s_instance = nullptr; + + void ReusableStringStream::cleanup() { + StringStreams::cleanup(); + } + + ReusableStringStream::ReusableStringStream() + : m_index( StringStreams::instance().add() ), + m_oss( StringStreams::instance().m_streams[m_index].get() ) + {} + + ReusableStringStream::~ReusableStringStream() { + static_cast<std::ostringstream*>( m_oss )->str(""); + m_oss->clear(); + StringStreams::instance().release( m_index ); + } + + auto ReusableStringStream::str() const -> std::string { + return static_cast<std::ostringstream*>( m_oss )->str(); + } + + /////////////////////////////////////////////////////////////////////////// + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { return std::cout; } + std::ostream& cerr() { return std::cerr; } + std::ostream& clog() { return std::clog; } +#endif +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_stream.cpp +// start catch_string_manip.cpp + +#include <algorithm> +#include <ostream> +#include <cstring> +#include <cctype> + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s[0] == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s[s.size()-1] == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + char toLowerCh(char c) { + return static_cast<char>( std::tolower( c ) ); + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << 's'; + return os; + } + +} +// end catch_string_manip.cpp +// start catch_stringref.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +#include <ostream> +#include <cstring> +#include <cstdint> + +namespace { + const uint32_t byte_2_lead = 0xC0; + const uint32_t byte_3_lead = 0xE0; + const uint32_t byte_4_lead = 0xF0; +} + +namespace Catch { + StringRef::StringRef( char const* rawChars ) noexcept + : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) ) + {} + + StringRef::operator std::string() const { + return std::string( m_start, m_size ); + } + + void StringRef::swap( StringRef& other ) noexcept { + std::swap( m_start, other.m_start ); + std::swap( m_size, other.m_size ); + std::swap( m_data, other.m_data ); + } + + auto StringRef::c_str() const -> char const* { + if( isSubstring() ) + const_cast<StringRef*>( this )->takeOwnership(); + return m_start; + } + auto StringRef::currentData() const noexcept -> char const* { + return m_start; + } + + auto StringRef::isOwned() const noexcept -> bool { + return m_data != nullptr; + } + auto StringRef::isSubstring() const noexcept -> bool { + return m_start[m_size] != '\0'; + } + + void StringRef::takeOwnership() { + if( !isOwned() ) { + m_data = new char[m_size+1]; + memcpy( m_data, m_start, m_size ); + m_data[m_size] = '\0'; + m_start = m_data; + } + } + auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef { + if( start < m_size ) + return StringRef( m_start+start, size ); + else + return StringRef(); + } + auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool { + return + size() == other.size() && + (std::strncmp( m_start, other.m_start, size() ) == 0); + } + auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool { + return !operator==( other ); + } + + auto StringRef::operator[](size_type index) const noexcept -> char { + return m_start[index]; + } + + auto StringRef::numberOfCharacters() const noexcept -> size_type { + size_type noChars = m_size; + // Make adjustments for uft encodings + for( size_type i=0; i < m_size; ++i ) { + char c = m_start[i]; + if( ( c & byte_2_lead ) == byte_2_lead ) { + noChars--; + if (( c & byte_3_lead ) == byte_3_lead ) + noChars--; + if( ( c & byte_4_lead ) == byte_4_lead ) + noChars--; + } + } + return noChars; + } + + auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string { + std::string str; + str.reserve( lhs.size() + rhs.size() ); + str += lhs; + str += rhs; + return str; + } + auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string { + return std::string( lhs ) + std::string( rhs ); + } + auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string { + return std::string( lhs ) + std::string( rhs ); + } + + auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& { + return os.write(str.currentData(), str.size()); + } + + auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& { + lhs.append(rhs.currentData(), rhs.size()); + return lhs; + } + +} // namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_stringref.cpp +// start catch_tag_alias.cpp + +namespace Catch { + TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {} +} +// end catch_tag_alias.cpp +// start catch_tag_alias_autoregistrar.cpp + +namespace Catch { + + RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) { + try { + getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); + } catch (...) { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + +} +// end catch_tag_alias_autoregistrar.cpp +// start catch_tag_alias_registry.cpp + +#include <sstream> + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + TagAlias const* TagAliasRegistry::find( std::string const& alias ) const { + auto it = m_registry.find( alias ); + if( it != m_registry.end() ) + return &(it->second); + else + return nullptr; + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( auto const& registryKvp : m_registry ) { + std::size_t pos = expandedTestSpec.find( registryKvp.first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + registryKvp.second.tag + + expandedTestSpec.substr( pos + registryKvp.first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { + CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'), + "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo ); + + CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second, + "error: tag alias, '" << alias << "' already registered.\n" + << "\tFirst seen at: " << find(alias)->lineInfo << "\n" + << "\tRedefined at: " << lineInfo ); + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + + ITagAliasRegistry const& ITagAliasRegistry::get() { + return getRegistryHub().getTagAliasRegistry(); + } + +} // end namespace Catch +// end catch_tag_alias_registry.cpp +// start catch_test_case_info.cpp + +#include <cctype> +#include <exception> +#include <algorithm> +#include <sstream> + +namespace Catch { + + TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else if( tag == "!benchmark" ) + return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); + else + return TestCaseInfo::None; + } + bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); + } + void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + CATCH_ENFORCE( !isReservedTag(tag), + "Tag name: [" << tag << "] is not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n" + << _lineInfo ); + } + + TestCase makeTestCase( ITestInvoker* _testCase, + std::string const& _className, + NameAndTags const& nameAndTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden = false; + + // Parse out tags + std::vector<std::string> tags; + std::string desc, tag; + bool inTag = false; + std::string _descOrTags = nameAndTags.tags; + for (char c : _descOrTags) { + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( ( prop & TestCaseInfo::IsHidden ) != 0 ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + tags.push_back( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + tags.push_back( "." ); + } + + TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, std::move(info) ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) { + std::sort(begin(tags), end(tags)); + tags.erase(std::unique(begin(tags), end(tags)), end(tags)); + testCaseInfo.lcaseTags.clear(); + + for( auto const& tag : tags ) { + std::string lcaseTag = toLower( tag ); + testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.push_back( lcaseTag ); + } + testCaseInfo.tags = std::move(tags); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::vector<std::string> const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + std::string TestCaseInfo::tagsAsString() const { + std::string ret; + // '[' and ']' per tag + std::size_t full_size = 2 * tags.size(); + for (const auto& tag : tags) { + full_size += tag.size(); + } + ret.reserve(full_size); + for (const auto& tag : tags) { + ret.push_back('['); + ret.append(tag); + ret.push_back(']'); + } + + return ret; + } + + TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch +// end catch_test_case_info.cpp +// start catch_test_case_registry_impl.cpp + +#include <sstream> + +namespace Catch { + + std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) { + + std::vector<TestCase> sorted = unsortedTestCases; + + switch( config.runOrder() ) { + case RunTests::InLexicographicalOrder: + std::sort( sorted.begin(), sorted.end() ); + break; + case RunTests::InRandomOrder: + seedRng( config ); + RandomNumberGenerator::shuffle( sorted ); + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; + } + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); + } + + void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) { + std::set<TestCase> seenFunctions; + for( auto const& function : functions ) { + auto prev = seenFunctions.insert( function ); + CATCH_ENFORCE( prev.second, + "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" + << "\tRedefined at " << function.getTestCaseInfo().lineInfo ); + } + } + + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector<TestCase> filtered; + filtered.reserve( testCases.size() ); + for( auto const& testCase : testCases ) + if( matchTest( testCase, testSpec, config ) ) + filtered.push_back( testCase ); + return filtered; + } + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + void TestRegistry::registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name.empty() ) { + ReusableStringStream rss; + rss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( rss.str() ) ); + } + m_functions.push_back( testCase ); + } + + std::vector<TestCase> const& TestRegistry::getAllTests() const { + return m_functions; + } + std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + /////////////////////////////////////////////////////////////////////////// + TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {} + + void TestInvokerAsFunction::invoke() const { + m_testAsFunction(); + } + + std::string extractClassName( StringRef const& classOrQualifiedMethodName ) { + std::string className = classOrQualifiedMethodName; + if( startsWith( className, '&' ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + +} // end namespace Catch +// end catch_test_case_registry_impl.cpp +// start catch_test_case_tracker.cpp + +#include <algorithm> +#include <assert.h> +#include <stdexcept> +#include <memory> +#include <sstream> + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { +namespace TestCaseTracking { + + NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) + : name( _name ), + location( _location ) + {} + + ITracker::~ITracker() = default; + + TrackerContext& TrackerContext::instance() { + static TrackerContext s_instance; + return s_instance; + } + + ITracker& TrackerContext::startRun() { + m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr ); + m_currentTracker = nullptr; + m_runState = Executing; + return *m_rootTracker; + } + + void TrackerContext::endRun() { + m_rootTracker.reset(); + m_currentTracker = nullptr; + m_runState = NotStarted; + } + + void TrackerContext::startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void TrackerContext::completeCycle() { + m_runState = CompletedCycle; + } + + bool TrackerContext::completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& TrackerContext::currentTracker() { + return *m_currentTracker; + } + void TrackerContext::setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + + TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} + bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const { + return + tracker->nameAndLocation().name == m_nameAndLocation.name && + tracker->nameAndLocation().location == m_nameAndLocation.location; + } + + TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : m_nameAndLocation( nameAndLocation ), + m_ctx( ctx ), + m_parent( parent ) + {} + + NameAndLocation const& TrackerBase::nameAndLocation() const { + return m_nameAndLocation; + } + bool TrackerBase::isComplete() const { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + bool TrackerBase::isSuccessfullyCompleted() const { + return m_runState == CompletedSuccessfully; + } + bool TrackerBase::isOpen() const { + return m_runState != NotStarted && !isComplete(); + } + bool TrackerBase::hasChildren() const { + return !m_children.empty(); + } + + void TrackerBase::addChild( ITrackerPtr const& child ) { + m_children.push_back( child ); + } + + ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) { + auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); + return( it != m_children.end() ) + ? *it + : nullptr; + } + ITracker& TrackerBase::parent() { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + void TrackerBase::openChild() { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + bool TrackerBase::isSectionTracker() const { return false; } + bool TrackerBase::isIndexTracker() const { return false; } + + void TrackerBase::open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + void TrackerBase::close() { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NeedsAnotherRun: + break; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + case NotStarted: + case CompletedSuccessfully: + case Failed: + CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState ); + + default: + CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState ); + } + moveToParent(); + m_ctx.completeCycle(); + } + void TrackerBase::fail() { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + void TrackerBase::markAsNeedingAnotherRun() { + m_runState = NeedsAnotherRun; + } + + void TrackerBase::moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void TrackerBase::moveToThis() { + m_ctx.setCurrentTracker( this ); + } + + SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ) + { + if( parent ) { + while( !parent->isSectionTracker() ) + parent = &parent->parent(); + + SectionTracker& parentSection = static_cast<SectionTracker&>( *parent ); + addNextFilters( parentSection.m_filters ); + } + } + + bool SectionTracker::isSectionTracker() const { return true; } + + SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { + std::shared_ptr<SectionTracker> section; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = std::static_pointer_cast<SectionTracker>( childTracker ); + } + else { + section = std::make_shared<SectionTracker>( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() ) + section->tryOpen(); + return *section; + } + + void SectionTracker::tryOpen() { + if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) + open(); + } + + void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) { + if( !filters.empty() ) { + m_filters.push_back(""); // Root - should never be consulted + m_filters.push_back(""); // Test Case - not a section filter + m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); + } + } + void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) { + if( filters.size() > 1 ) + m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); + } + + IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( nameAndLocation, ctx, parent ), + m_size( size ) + {} + + bool IndexTracker::isIndexTracker() const { return true; } + + IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { + std::shared_ptr<IndexTracker> tracker; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isIndexTracker() ); + tracker = std::static_pointer_cast<IndexTracker>( childTracker ); + } + else { + tracker = std::make_shared<IndexTracker>( nameAndLocation, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int IndexTracker::index() const { return m_index; } + + void IndexTracker::moveNext() { + m_index++; + m_children.clear(); + } + + void IndexTracker::close() { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_test_case_tracker.cpp +// start catch_test_registry.cpp + +namespace Catch { + + auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* { + return new(std::nothrow) TestInvokerAsFunction( testAsFunction ); + } + + NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {} + + AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept { + try { + getMutableRegistryHub() + .registerTest( + makeTestCase( + invoker, + extractClassName( classOrMethod ), + nameAndTags, + lineInfo)); + } catch (...) { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + + AutoReg::~AutoReg() = default; +} +// end catch_test_registry.cpp +// start catch_test_spec.cpp + +#include <algorithm> +#include <string> +#include <vector> +#include <memory> + +namespace Catch { + + TestSpec::Pattern::~Pattern() = default; + TestSpec::NamePattern::~NamePattern() = default; + TestSpec::TagPattern::~TagPattern() = default; + TestSpec::ExcludedPattern::~ExcludedPattern() = default; + + TestSpec::NamePattern::NamePattern( std::string const& name ) + : m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( toLower( testCase.name ) ); + } + + TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} + bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const { + return std::find(begin(testCase.lcaseTags), + end(testCase.lcaseTags), + m_tag) != end(testCase.lcaseTags); + } + + TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} + bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } + + bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const { + // All patterns in a filter must match for the filter to be a match + for( auto const& pattern : m_patterns ) { + if( !pattern->matches( testCase ) ) + return false; + } + return true; + } + + bool TestSpec::hasFilters() const { + return !m_filters.empty(); + } + bool TestSpec::matches( TestCaseInfo const& testCase ) const { + // A TestSpec matches if any filter matches + for( auto const& filter : m_filters ) + if( filter.matches( testCase ) ) + return true; + return false; + } +} +// end catch_test_spec.cpp +// start catch_test_spec_parser.cpp + +namespace Catch { + + TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + + TestSpecParser& TestSpecParser::parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases( arg ); + m_escapeChars.clear(); + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + visitChar( m_arg[m_pos] ); + if( m_mode == Name ) + addPattern<TestSpec::NamePattern>(); + return *this; + } + TestSpec TestSpecParser::testSpec() { + addFilter(); + return m_testSpec; + } + + void TestSpecParser::visitChar( char c ) { + if( m_mode == None ) { + switch( c ) { + case ' ': return; + case '~': m_exclusion = true; return; + case '[': return startNewMode( Tag, ++m_pos ); + case '"': return startNewMode( QuotedName, ++m_pos ); + case '\\': return escape(); + default: startNewMode( Name, m_pos ); break; + } + } + if( m_mode == Name ) { + if( c == ',' ) { + addPattern<TestSpec::NamePattern>(); + addFilter(); + } + else if( c == '[' ) { + if( subString() == "exclude:" ) + m_exclusion = true; + else + addPattern<TestSpec::NamePattern>(); + startNewMode( Tag, ++m_pos ); + } + else if( c == '\\' ) + escape(); + } + else if( m_mode == EscapedName ) + m_mode = Name; + else if( m_mode == QuotedName && c == '"' ) + addPattern<TestSpec::NamePattern>(); + else if( m_mode == Tag && c == ']' ) + addPattern<TestSpec::TagPattern>(); + } + void TestSpecParser::startNewMode( Mode mode, std::size_t start ) { + m_mode = mode; + m_start = start; + } + void TestSpecParser::escape() { + if( m_mode == None ) + m_start = m_pos; + m_mode = EscapedName; + m_escapeChars.push_back( m_pos ); + } + std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); } + + void TestSpecParser::addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + + TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch +// end catch_test_spec_parser.cpp +// start catch_timer.cpp + +#include <chrono> + +static const uint64_t nanosecondsInSecond = 1000000000; + +namespace Catch { + + auto getCurrentNanosecondsSinceEpoch() -> uint64_t { + return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); + } + + auto estimateClockResolution() -> uint64_t { + uint64_t sum = 0; + static const uint64_t iterations = 1000000; + + auto startTime = getCurrentNanosecondsSinceEpoch(); + + for( std::size_t i = 0; i < iterations; ++i ) { + + uint64_t ticks; + uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); + do { + ticks = getCurrentNanosecondsSinceEpoch(); + } while( ticks == baseTicks ); + + auto delta = ticks - baseTicks; + sum += delta; + + // If we have been calibrating for over 3 seconds -- the clock + // is terrible and we should move on. + // TBD: How to signal that the measured resolution is probably wrong? + if (ticks > startTime + 3 * nanosecondsInSecond) { + return sum / i; + } + } + + // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers + // - and potentially do more iterations if there's a high variance. + return sum/iterations; + } + auto getEstimatedClockResolution() -> uint64_t { + static auto s_resolution = estimateClockResolution(); + return s_resolution; + } + + void Timer::start() { + m_nanoseconds = getCurrentNanosecondsSinceEpoch(); + } + auto Timer::getElapsedNanoseconds() const -> uint64_t { + return getCurrentNanosecondsSinceEpoch() - m_nanoseconds; + } + auto Timer::getElapsedMicroseconds() const -> uint64_t { + return getElapsedNanoseconds()/1000; + } + auto Timer::getElapsedMilliseconds() const -> unsigned int { + return static_cast<unsigned int>(getElapsedMicroseconds()/1000); + } + auto Timer::getElapsedSeconds() const -> double { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch +// end catch_timer.cpp +// start catch_tostring.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +# pragma clang diagnostic ignored "-Wglobal-constructors" +#endif + +// Enable specific decls locally +#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#include <cmath> +#include <iomanip> + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _{ + int asInt; + char asChar[sizeof (int)]; + } u; + + u.asInt = 1; + return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) { + // Reverse order for little endian architectures + int i = 0, end = static_cast<int>( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast<unsigned char const *>(object); + ReusableStringStream rss; + rss << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + rss << std::setw(2) << static_cast<unsigned>(bytes[i]); + return rss.str(); + } +} + +template<typename T> +std::string fpToString( T value, int precision ) { + if (std::isnan(value)) { + return "nan"; + } + + ReusableStringStream rss; + rss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = rss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +//// ======================================================= //// +// +// Out-of-line defs for full specialization of StringMaker +// +//// ======================================================= //// + +std::string StringMaker<std::string>::convert(const std::string& str) { + if (!getCurrentContext().getConfig()->showInvisibles()) { + return '"' + str + '"'; + } + + std::string s("\""); + for (char c : str) { + switch (c) { + case '\n': + s.append("\\n"); + break; + case '\t': + s.append("\\t"); + break; + default: + s.push_back(c); + break; + } + } + s.append("\""); + return s; +} + +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) { + std::string s; + s.reserve(wstr.size()); + for (auto c : wstr) { + s += (c <= 0xff) ? static_cast<char>(c) : '?'; + } + return ::Catch::Detail::stringify(s); +} +#endif + +std::string StringMaker<char const*>::convert(char const* str) { + if (str) { + return ::Catch::Detail::stringify(std::string{ str }); + } else { + return{ "{null string}" }; + } +} +std::string StringMaker<char*>::convert(char* str) { + if (str) { + return ::Catch::Detail::stringify(std::string{ str }); + } else { + return{ "{null string}" }; + } +} +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{ str }); + } else { + return{ "{null string}" }; + } +} +std::string StringMaker<wchar_t *>::convert(wchar_t * str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{ str }); + } else { + return{ "{null string}" }; + } +} +#endif + +std::string StringMaker<int>::convert(int value) { + return ::Catch::Detail::stringify(static_cast<long long>(value)); +} +std::string StringMaker<long>::convert(long value) { + return ::Catch::Detail::stringify(static_cast<long long>(value)); +} +std::string StringMaker<long long>::convert(long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker<unsigned int>::convert(unsigned int value) { + return ::Catch::Detail::stringify(static_cast<unsigned long long>(value)); +} +std::string StringMaker<unsigned long>::convert(unsigned long value) { + return ::Catch::Detail::stringify(static_cast<unsigned long long>(value)); +} +std::string StringMaker<unsigned long long>::convert(unsigned long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker<bool>::convert(bool b) { + return b ? "true" : "false"; +} + +std::string StringMaker<char>::convert(char value) { + if (value == '\r') { + return "'\\r'"; + } else if (value == '\f') { + return "'\\f'"; + } else if (value == '\n') { + return "'\\n'"; + } else if (value == '\t') { + return "'\\t'"; + } else if ('\0' <= value && value < ' ') { + return ::Catch::Detail::stringify(static_cast<unsigned int>(value)); + } else { + char chstr[] = "' '"; + chstr[1] = value; + return chstr; + } +} +std::string StringMaker<signed char>::convert(signed char c) { + return ::Catch::Detail::stringify(static_cast<char>(c)); +} +std::string StringMaker<unsigned char>::convert(unsigned char c) { + return ::Catch::Detail::stringify(static_cast<char>(c)); +} + +std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) { + return "nullptr"; +} + +std::string StringMaker<float>::convert(float value) { + return fpToString(value, 5) + 'f'; +} +std::string StringMaker<double>::convert(double value) { + return fpToString(value, 10); +} + +std::string ratio_string<std::atto>::symbol() { return "a"; } +std::string ratio_string<std::femto>::symbol() { return "f"; } +std::string ratio_string<std::pico>::symbol() { return "p"; } +std::string ratio_string<std::nano>::symbol() { return "n"; } +std::string ratio_string<std::micro>::symbol() { return "u"; } +std::string ratio_string<std::milli>::symbol() { return "m"; } + +} // end namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +// end catch_tostring.cpp +// start catch_totals.cpp + +namespace Catch { + + Counts Counts::operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + + Counts& Counts::operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t Counts::total() const { + return passed + failed + failedButOk; + } + bool Counts::allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool Counts::allOk() const { + return failed == 0; + } + + Totals Totals::operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals& Totals::operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Totals Totals::delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + +} +// end catch_totals.cpp +// start catch_uncaught_exceptions.cpp + +#include <exception> + +namespace Catch { + bool uncaught_exceptions() { +#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + return std::uncaught_exceptions() > 0; +#else + return std::uncaught_exception(); +#endif + } +} // end namespace Catch +// end catch_uncaught_exceptions.cpp +// start catch_version.cpp + +#include <ostream> + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << '.' + << version.minorVersion << '.' + << version.patchNumber; + // branchName is never null -> 0th char is \0 if it is empty + if (version.branchName[0]) { + os << '-' << version.branchName + << '.' << version.buildNumber; + } + return os; + } + + Version const& libraryVersion() { + static Version version( 2, 2, 2, "", 0 ); + return version; + } + +} +// end catch_version.cpp +// start catch_wildcard_pattern.cpp + +#include <sstream> + +namespace Catch { + + WildcardPattern::WildcardPattern( std::string const& pattern, + CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_pattern( adjustCase( pattern ) ) + { + if( startsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd ); + } + } + + bool WildcardPattern::matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == adjustCase( str ); + case WildcardAtStart: + return endsWith( adjustCase( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( adjustCase( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( adjustCase( str ), m_pattern ); + default: + CATCH_INTERNAL_ERROR( "Unknown enum" ); + } + } + + std::string WildcardPattern::adjustCase( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; + } +} +// end catch_wildcard_pattern.cpp +// start catch_xmlwriter.cpp + +#include <iomanip> + +using uchar = unsigned char; + +namespace Catch { + +namespace { + + size_t trailingBytes(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return 2; + } + if ((c & 0xF0) == 0xE0) { + return 3; + } + if ((c & 0xF8) == 0xF0) { + return 4; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + uint32_t headerValue(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return c & 0x1F; + } + if ((c & 0xF0) == 0xE0) { + return c & 0x0F; + } + if ((c & 0xF8) == 0xF0) { + return c & 0x07; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + void hexEscapeChar(std::ostream& os, unsigned char c) { + os << "\\x" + << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast<int>(c); + } + +} // anonymous namespace + + XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void XmlEncode::encodeTo( std::ostream& os ) const { + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { + uchar c = m_str[idx]; + switch (c) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') + os << ">"; + else + os << c; + break; + + case '\"': + if (m_forWhat == ForAttributes) + os << """; + else + os << c; + break; + + default: + // Check for control characters and invalid utf-8 + + // Escape control characters in standard ascii + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { + hexEscapeChar(os, c); + break; + } + + // Plain ASCII: Write it to stream + if (c < 0x7F) { + os << c; + break; + } + + // UTF-8 territory + // Check if the encoding is valid and if it is not, hex escape bytes. + // Important: We do not check the exact decoded values for validity, only the encoding format + // First check that this bytes is a valid lead byte: + // This means that it is not encoded as 1111 1XXX + // Or as 10XX XXXX + if (c < 0xC0 || + c >= 0xF8) { + hexEscapeChar(os, c); + break; + } + + auto encBytes = trailingBytes(c); + // Are there enough bytes left to avoid accessing out-of-bounds memory? + if (idx + encBytes - 1 >= m_str.size()) { + hexEscapeChar(os, c); + break; + } + // The header is valid, check data + // The next encBytes bytes must together be a valid utf-8 + // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) + bool valid = true; + uint32_t value = headerValue(c); + for (std::size_t n = 1; n < encBytes; ++n) { + uchar nc = m_str[idx + n]; + valid &= ((nc & 0xC0) == 0x80); + value = (value << 6) | (nc & 0x3F); + } + + if ( + // Wrong bit pattern of following bytes + (!valid) || + // Overlong encodings + (value < 0x80) || + (0x80 <= value && value < 0x800 && encBytes > 2) || + (0x800 < value && value < 0x10000 && encBytes > 3) || + // Encoded value out of range + (value >= 0x110000) + ) { + hexEscapeChar(os, c); + break; + } + + // If we got here, this is in fact a valid(ish) utf-8 sequence + for (std::size_t n = 0; n < encBytes; ++n) { + os << m_str[idx + n]; + } + idx += encBytes - 1; + break; + } + } + } + + std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept + : m_writer( other.m_writer ){ + other.m_writer = nullptr; + } + XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept { + if ( m_writer ) { + m_writer->endElement(); + } + m_writer = other.m_writer; + other.m_writer = nullptr; + return *this; + } + + XmlWriter::ScopedElement::~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { + m_writer->writeText( text, indent ); + return *this; + } + + XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) + { + writeDeclaration(); + } + + XmlWriter::~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& XmlWriter::startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& XmlWriter::endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } + else { + m_os << m_indent << "</" << m_tags.back() << ">"; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + m_os << m_indent; + m_os << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + XmlWriter& XmlWriter::writeComment( std::string const& text ) { + ensureTagClosed(); + m_os << m_indent << "<!--" << text << "-->"; + m_needsNewline = true; + return *this; + } + + void XmlWriter::writeStylesheetRef( std::string const& url ) { + m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n"; + } + + XmlWriter& XmlWriter::writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; + } + + void XmlWriter::ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } + } + + void XmlWriter::writeDeclaration() { + m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; + } + + void XmlWriter::newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } +} +// end catch_xmlwriter.cpp +// start catch_reporter_bases.cpp + +#include <cstring> +#include <cfloat> +#include <cstdio> +#include <assert.h> +#include <memory> + +namespace Catch { + void prepareExpandedExpression(AssertionResult& result) { + result.getExpandedExpression(); + } + + // Because formatting using c++ streams is stateful, drop down to C is required + // Alternatively we could use stringstream, but its performance is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; + + // Save previous errno, to prevent sprintf from overwriting it + ErrnoGuard guard; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); + } + + TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config) + :StreamingReporterBase(_config) {} + + void TestEventListenerBase::assertionStarting(AssertionInfo const &) {} + + bool TestEventListenerBase::assertionEnded(AssertionStats const &) { + return false; + } + +} // end namespace Catch +// end catch_reporter_bases.cpp +// start catch_reporter_compact.cpp + +namespace { + +#ifdef CATCH_PLATFORM_MAC + const char* failedString() { return "FAILED"; } + const char* passedString() { return "PASSED"; } +#else + const char* failedString() { return "failed"; } + const char* passedString() { return "passed"; } +#endif + + // Colour::LightGrey + Catch::Colour::Code dimColour() { return Catch::Colour::FileName; } + + std::string bothOrAll( std::size_t count ) { + return count == 1 ? std::string() : + count == 2 ? "both " : "all " ; + } + +} // anon namespace + +namespace Catch { +namespace { +// Colour, message variants: +// - white: No tests ran. +// - red: Failed [both/all] N test cases, failed [both/all] M assertions. +// - white: Passed [both/all] N test cases (no assertions). +// - red: Failed N tests cases, failed M assertions. +// - green: Passed [both/all] N tests cases with M assertions. +void printTotals(std::ostream& out, const Totals& totals) { + if (totals.testCases.total() == 0) { + out << "No tests ran."; + } else if (totals.testCases.failed == totals.testCases.total()) { + Colour colour(Colour::ResultError); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll(totals.assertions.failed) : std::string(); + out << + "Failed " << bothOrAll(totals.testCases.failed) + << pluralise(totals.testCases.failed, "test case") << ", " + "failed " << qualify_assertions_failed << + pluralise(totals.assertions.failed, "assertion") << '.'; + } else if (totals.assertions.total() == 0) { + out << + "Passed " << bothOrAll(totals.testCases.total()) + << pluralise(totals.testCases.total(), "test case") + << " (no assertions)."; + } else if (totals.assertions.failed) { + Colour colour(Colour::ResultError); + out << + "Failed " << pluralise(totals.testCases.failed, "test case") << ", " + "failed " << pluralise(totals.assertions.failed, "assertion") << '.'; + } else { + Colour colour(Colour::ResultSuccess); + out << + "Passed " << bothOrAll(totals.testCases.passed) + << pluralise(totals.testCases.passed, "test case") << + " with " << pluralise(totals.assertions.passed, "assertion") << '.'; + } +} + +// Implementation of CompactReporter formatting +class AssertionPrinter { +public: + AssertionPrinter& operator= (AssertionPrinter const&) = delete; + AssertionPrinter(AssertionPrinter const&) = delete; + AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) + : stream(_stream) + , result(_stats.assertionResult) + , messages(_stats.infoMessages) + , itMessage(_stats.infoMessages.begin()) + , printInfoMessages(_printInfoMessages) {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch (result.getResultType()) { + case ResultWas::Ok: + printResultType(Colour::ResultSuccess, passedString()); + printOriginalExpression(); + printReconstructedExpression(); + if (!result.hasExpression()) + printRemainingMessages(Colour::None); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) + printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok")); + else + printResultType(Colour::Error, failedString()); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType(Colour::Error, failedString()); + printIssue("unexpected exception with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType(Colour::Error, failedString()); + printIssue("fatal error condition with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType(Colour::Error, failedString()); + printIssue("expected exception, got none"); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType(Colour::None, "info"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType(Colour::None, "warning"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType(Colour::Error, failedString()); + printIssue("explicitly"); + printRemainingMessages(Colour::None); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType(Colour::Error, "** internal error **"); + break; + } + } + +private: + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ':'; + } + + void printResultType(Colour::Code colour, std::string const& passOrFail) const { + if (!passOrFail.empty()) { + { + Colour colourGuard(colour); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue(std::string const& issue) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if (result.hasExpression()) { + stream << ';'; + { + Colour colour(dimColour()); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if (result.hasExpression()) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + { + Colour colour(dimColour()); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if (itMessage != messages.end()) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages(Colour::Code colour = dimColour()) { + if (itMessage == messages.end()) + return; + + // using messages.end() directly yields (or auto) compilation error: + std::vector<MessageInfo>::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd)); + + { + Colour colourGuard(colour); + stream << " with " << pluralise(N, "message") << ':'; + } + + for (; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || itMessage->type != ResultWas::Info) { + stream << " '" << itMessage->message << '\''; + if (++itMessage != itEnd) { + Colour colourGuard(dimColour()); + stream << " and"; + } + } + } + } + +private: + std::ostream& stream; + AssertionResult const& result; + std::vector<MessageInfo> messages; + std::vector<MessageInfo>::const_iterator itMessage; + bool printInfoMessages; +}; + +} // anon namespace + + std::string CompactReporter::getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + ReporterPreferences CompactReporter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + void CompactReporter::noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + void CompactReporter::assertionStarting( AssertionInfo const& ) {} + + bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + } + + void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( stream, _testRunStats.totals ); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + CompactReporter::~CompactReporter() {} + + CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch +// end catch_reporter_compact.cpp +// start catch_reporter_console.cpp + +#include <cfloat> +#include <cstdio> + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + +namespace { + +// Formatter impl for ConsoleReporter +class ConsoleAssertionPrinter { +public: + ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete; + ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete; + ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) + : stream(_stream), + stats(_stats), + result(_stats.assertionResult), + colour(Colour::None), + message(result.getMessage()), + messages(_stats.infoMessages), + printInfoMessages(_printInfoMessages) { + switch (result.getResultType()) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with "; + if (_stats.infoMessages.size() == 1) + messageLabel += "message"; + if (_stats.infoMessages.size() > 1) + messageLabel += "messages"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if (_stats.infoMessages.size() == 1) + messageLabel = "explicitly with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if (stats.totals.assertions.total() > 0) { + if (result.isOk()) + stream << '\n'; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } else { + stream << '\n'; + } + printMessage(); + } + +private: + void printResultType() const { + if (!passOrFail.empty()) { + Colour colourGuard(colour); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if (result.hasExpression()) { + Colour colourGuard(Colour::OriginalExpression); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + stream << "with expansion:\n"; + Colour colourGuard(Colour::ReconstructedExpression); + stream << Column(result.getExpandedExpression()).indent(2) << '\n'; + } + } + void printMessage() const { + if (!messageLabel.empty()) + stream << messageLabel << ':' << '\n'; + for (auto const& msg : messages) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || msg.type != ResultWas::Info) + stream << Column(msg.message).indent(2) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector<MessageInfo> messages; + bool printInfoMessages; +}; + +std::size_t makeRatio(std::size_t number, std::size_t total) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0; + return (ratio == 0 && number > 0) ? 1 : ratio; +} + +std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) { + if (i > j && i > k) + return i; + else if (j > k) + return j; + else + return k; +} + +struct ColumnInfo { + enum Justification { Left, Right }; + std::string name; + int width; + Justification justification; +}; +struct ColumnBreak {}; +struct RowBreak {}; + +class Duration { + enum class Unit { + Auto, + Nanoseconds, + Microseconds, + Milliseconds, + Seconds, + Minutes + }; + static const uint64_t s_nanosecondsInAMicrosecond = 1000; + static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond; + static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond; + static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond; + + uint64_t m_inNanoseconds; + Unit m_units; + +public: + explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto) + : m_inNanoseconds(inNanoseconds), + m_units(units) { + if (m_units == Unit::Auto) { + if (m_inNanoseconds < s_nanosecondsInAMicrosecond) + m_units = Unit::Nanoseconds; + else if (m_inNanoseconds < s_nanosecondsInAMillisecond) + m_units = Unit::Microseconds; + else if (m_inNanoseconds < s_nanosecondsInASecond) + m_units = Unit::Milliseconds; + else if (m_inNanoseconds < s_nanosecondsInAMinute) + m_units = Unit::Seconds; + else + m_units = Unit::Minutes; + } + + } + + auto value() const -> double { + switch (m_units) { + case Unit::Microseconds: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond); + case Unit::Milliseconds: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond); + case Unit::Seconds: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond); + case Unit::Minutes: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute); + default: + return static_cast<double>(m_inNanoseconds); + } + } + auto unitsAsString() const -> std::string { + switch (m_units) { + case Unit::Nanoseconds: + return "ns"; + case Unit::Microseconds: + return "µs"; + case Unit::Milliseconds: + return "ms"; + case Unit::Seconds: + return "s"; + case Unit::Minutes: + return "m"; + default: + return "** internal error **"; + } + + } + friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& { + return os << duration.value() << " " << duration.unitsAsString(); + } +}; +} // end anon namespace + +class TablePrinter { + std::ostream& m_os; + std::vector<ColumnInfo> m_columnInfos; + std::ostringstream m_oss; + int m_currentColumn = -1; + bool m_isOpen = false; + +public: + TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos ) + : m_os( os ), + m_columnInfos( std::move( columnInfos ) ) {} + + auto columnInfos() const -> std::vector<ColumnInfo> const& { + return m_columnInfos; + } + + void open() { + if (!m_isOpen) { + m_isOpen = true; + *this << RowBreak(); + for (auto const& info : m_columnInfos) + *this << info.name << ColumnBreak(); + *this << RowBreak(); + m_os << Catch::getLineOfChars<'-'>() << "\n"; + } + } + void close() { + if (m_isOpen) { + *this << RowBreak(); + m_os << std::endl; + m_isOpen = false; + } + } + + template<typename T> + friend TablePrinter& operator << (TablePrinter& tp, T const& value) { + tp.m_oss << value; + return tp; + } + + friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) { + auto colStr = tp.m_oss.str(); + // This takes account of utf8 encodings + auto strSize = Catch::StringRef(colStr).numberOfCharacters(); + tp.m_oss.str(""); + tp.open(); + if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) { + tp.m_currentColumn = -1; + tp.m_os << "\n"; + } + tp.m_currentColumn++; + + auto colInfo = tp.m_columnInfos[tp.m_currentColumn]; + auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width)) + ? std::string(colInfo.width - (strSize + 2), ' ') + : std::string(); + if (colInfo.justification == ColumnInfo::Left) + tp.m_os << colStr << padding << " "; + else + tp.m_os << padding << colStr << " "; + return tp; + } + + friend TablePrinter& operator << (TablePrinter& tp, RowBreak) { + if (tp.m_currentColumn > 0) { + tp.m_os << "\n"; + tp.m_currentColumn = -1; + } + return tp; + } +}; + +ConsoleReporter::ConsoleReporter(ReporterConfig const& config) + : StreamingReporterBase(config), + m_tablePrinter(new TablePrinter(config.stream(), + { + { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left }, + { "iters", 8, ColumnInfo::Right }, + { "elapsed ns", 14, ColumnInfo::Right }, + { "average", 14, ColumnInfo::Right } + })) {} +ConsoleReporter::~ConsoleReporter() = default; + +std::string ConsoleReporter::getDescription() { + return "Reports test results as plain lines of text"; +} + +void ConsoleReporter::noMatchingTestCases(std::string const& spec) { + stream << "No test cases matched '" << spec << '\'' << std::endl; +} + +void ConsoleReporter::assertionStarting(AssertionInfo const&) {} + +bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + // Drop out if result was successful but we're not printing them. + if (!includeResults && result.getResultType() != ResultWas::Warning) + return false; + + lazyPrint(); + + ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults); + printer.print(); + stream << std::endl; + return true; +} + +void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting(_sectionInfo); +} +void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) { + m_tablePrinter->close(); + if (_sectionStats.missingAssertions) { + lazyPrint(); + Colour colour(Colour::ResultError); + if (m_sectionStack.size() > 1) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + if (m_headerPrinted) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded(_sectionStats); +} + +void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) { + lazyPrintWithoutClosingBenchmarkTable(); + + auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) ); + + bool firstLine = true; + for (auto line : nameCol) { + if (!firstLine) + (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak(); + else + firstLine = false; + + (*m_tablePrinter) << line << ColumnBreak(); + } +} +void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) { + Duration average(stats.elapsedTimeInNanoseconds / stats.iterations); + (*m_tablePrinter) + << stats.iterations << ColumnBreak() + << stats.elapsedTimeInNanoseconds << ColumnBreak() + << average << ColumnBreak(); +} + +void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) { + m_tablePrinter->close(); + StreamingReporterBase::testCaseEnded(_testCaseStats); + m_headerPrinted = false; +} +void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) { + if (currentGroupInfo.used) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals(_testGroupStats.totals); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded(_testGroupStats); +} +void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) { + printTotalsDivider(_testRunStats.totals); + printTotals(_testRunStats.totals); + stream << std::endl; + StreamingReporterBase::testRunEnded(_testRunStats); +} + +void ConsoleReporter::lazyPrint() { + + m_tablePrinter->close(); + lazyPrintWithoutClosingBenchmarkTable(); +} + +void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { + + if (!currentTestRunInfo.used) + lazyPrintRunInfo(); + if (!currentGroupInfo.used) + lazyPrintGroupInfo(); + + if (!m_headerPrinted) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } +} +void ConsoleReporter::lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour(Colour::SecondaryText); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion() << " host application.\n" + << "Run with -? for options\n\n"; + + if (m_config->rngSeed() != 0) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; +} +void ConsoleReporter::lazyPrintGroupInfo() { + if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) { + printClosedHeader("Group: " + currentGroupInfo->name); + currentGroupInfo.used = true; + } +} +void ConsoleReporter::printTestCaseAndSectionHeader() { + assert(!m_sectionStack.empty()); + printOpenHeader(currentTestCaseInfo->name); + + if (m_sectionStack.size() > 1) { + Colour colourGuard(Colour::Headers); + + auto + it = m_sectionStack.begin() + 1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for (; it != itEnd; ++it) + printHeaderString(it->name, 2); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + if (!lineInfo.empty()) { + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard(Colour::FileName); + stream << lineInfo << '\n'; + } + stream << getLineOfChars<'.'>() << '\n' << std::endl; +} + +void ConsoleReporter::printClosedHeader(std::string const& _name) { + printOpenHeader(_name); + stream << getLineOfChars<'.'>() << '\n'; +} +void ConsoleReporter::printOpenHeader(std::string const& _name) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard(Colour::Headers); + printHeaderString(_name); + } +} + +// if string has a : in first line will set indent to follow it on +// subsequent lines +void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) { + std::size_t i = _string.find(": "); + if (i != std::string::npos) + i += 2; + else + i = 0; + stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n'; +} + +struct SummaryColumn { + + SummaryColumn( std::string _label, Colour::Code _colour ) + : label( std::move( _label ) ), + colour( _colour ) {} + SummaryColumn addRow( std::size_t count ) { + ReusableStringStream rss; + rss << count; + std::string row = rss.str(); + for (auto& oldRow : rows) { + while (oldRow.size() < row.size()) + oldRow = ' ' + oldRow; + while (oldRow.size() > row.size()) + row = ' ' + row; + } + rows.push_back(row); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector<std::string> rows; + +}; + +void ConsoleReporter::printTotals( Totals const& totals ) { + if (totals.testCases.total() == 0) { + stream << Colour(Colour::Warning) << "No tests ran\n"; + } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) { + stream << Colour(Colour::ResultSuccess) << "All tests passed"; + stream << " (" + << pluralise(totals.assertions.passed, "assertion") << " in " + << pluralise(totals.testCases.passed, "test case") << ')' + << '\n'; + } else { + + std::vector<SummaryColumn> columns; + columns.push_back(SummaryColumn("", Colour::None) + .addRow(totals.testCases.total()) + .addRow(totals.assertions.total())); + columns.push_back(SummaryColumn("passed", Colour::Success) + .addRow(totals.testCases.passed) + .addRow(totals.assertions.passed)); + columns.push_back(SummaryColumn("failed", Colour::ResultError) + .addRow(totals.testCases.failed) + .addRow(totals.assertions.failed)); + columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure) + .addRow(totals.testCases.failedButOk) + .addRow(totals.assertions.failedButOk)); + + printSummaryRow("test cases", columns, 0); + printSummaryRow("assertions", columns, 1); + } +} +void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) { + for (auto col : cols) { + std::string value = col.rows[row]; + if (col.label.empty()) { + stream << label << ": "; + if (value != "0") + stream << value; + else + stream << Colour(Colour::Warning) << "- none -"; + } else if (value != "0") { + stream << Colour(Colour::LightGrey) << " | "; + stream << Colour(col.colour) + << value << ' ' << col.label; + } + } + stream << '\n'; +} + +void ConsoleReporter::printTotalsDivider(Totals const& totals) { + if (totals.testCases.total() > 0) { + std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total()); + std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total()); + std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total()); + while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)++; + while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)--; + + stream << Colour(Colour::Error) << std::string(failedRatio, '='); + stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); + if (totals.testCases.allPassed()) + stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); + else + stream << Colour(Colour::Success) << std::string(passedRatio, '='); + } else { + stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); + } + stream << '\n'; +} +void ConsoleReporter::printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; +} + +CATCH_REGISTER_REPORTER("console", ConsoleReporter) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_console.cpp +// start catch_reporter_junit.cpp + +#include <assert.h> +#include <sstream> +#include <ctime> +#include <algorithm> + +namespace Catch { + + namespace { + std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm* timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + + std::string fileNameTag(const std::vector<std::string> &tags) { + auto it = std::find_if(begin(tags), + end(tags), + [] (std::string const& tag) {return tag.front() == '#'; }); + if (it != tags.end()) + return it->substr(1); + return std::string(); + } + } // anonymous namespace + + JunitReporter::JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + JunitReporter::~JunitReporter() {} + + std::string JunitReporter::getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {} + + void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) { + suiteTimer.start(); + stdOutForSuite.clear(); + stdErrForSuite.clear(); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) { + m_okToFail = testCaseInfo.okToFail(); + } + + bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + stdOutForSuite += testCaseStats.stdOut; + stdErrForSuite += testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + void JunitReporter::testRunEndedCumulative() { + xml.endElement(); + } + + void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "timestamp", getCurrentTimestamp() ); + + // Write test cases + for( auto const& child : groupNode.children ) + writeTestCase( *child ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false ); + } + + void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + className = fileNameTag(stats.testInfo.tags); + if ( className.empty() ) + className = "global"; + } + + if ( !m_config->name().empty() ) + className = m_config->name() + "." + className; + + writeSection( className, "", rootSection ); + } + + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode ) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + '/' + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); + } + for( auto const& childNode : sectionNode.childSections ) + if( className.empty() ) + writeSection( name, "", *childNode ); + else + writeSection( className, name, *childNode ); + } + + void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { + for( auto const& assertion : sectionNode.assertions ) + writeAssertion( assertion ); + } + + void JunitReporter::writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpandedExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + ReusableStringStream rss; + if( !result.getMessage().empty() ) + rss << result.getMessage() << '\n'; + for( auto const& msg : stats.infoMessages ) + if( msg.type == ResultWas::Info ) + rss << msg.message << '\n'; + + rss << "at " << result.getSourceInfo(); + xml.writeText( rss.str(), false ); + } + } + + CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch +// end catch_reporter_junit.cpp +// start catch_reporter_multi.cpp + +namespace Catch { + + void MultipleReporters::add( IStreamingReporterPtr&& reporter ) { + m_reporters.push_back( std::move( reporter ) ); + } + + ReporterPreferences MultipleReporters::getPreferences() const { + return m_reporters[0]->getPreferences(); + } + + std::set<Verbosity> MultipleReporters::getSupportedVerbosities() { + return std::set<Verbosity>{ }; + } + + void MultipleReporters::noMatchingTestCases( std::string const& spec ) { + for( auto const& reporter : m_reporters ) + reporter->noMatchingTestCases( spec ); + } + + void MultipleReporters::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) { + for( auto const& reporter : m_reporters ) + reporter->benchmarkStarting( benchmarkInfo ); + } + void MultipleReporters::benchmarkEnded( BenchmarkStats const& benchmarkStats ) { + for( auto const& reporter : m_reporters ) + reporter->benchmarkEnded( benchmarkStats ); + } + + void MultipleReporters::testRunStarting( TestRunInfo const& testRunInfo ) { + for( auto const& reporter : m_reporters ) + reporter->testRunStarting( testRunInfo ); + } + + void MultipleReporters::testGroupStarting( GroupInfo const& groupInfo ) { + for( auto const& reporter : m_reporters ) + reporter->testGroupStarting( groupInfo ); + } + + void MultipleReporters::testCaseStarting( TestCaseInfo const& testInfo ) { + for( auto const& reporter : m_reporters ) + reporter->testCaseStarting( testInfo ); + } + + void MultipleReporters::sectionStarting( SectionInfo const& sectionInfo ) { + for( auto const& reporter : m_reporters ) + reporter->sectionStarting( sectionInfo ); + } + + void MultipleReporters::assertionStarting( AssertionInfo const& assertionInfo ) { + for( auto const& reporter : m_reporters ) + reporter->assertionStarting( assertionInfo ); + } + + // The return value indicates if the messages buffer should be cleared: + bool MultipleReporters::assertionEnded( AssertionStats const& assertionStats ) { + bool clearBuffer = false; + for( auto const& reporter : m_reporters ) + clearBuffer |= reporter->assertionEnded( assertionStats ); + return clearBuffer; + } + + void MultipleReporters::sectionEnded( SectionStats const& sectionStats ) { + for( auto const& reporter : m_reporters ) + reporter->sectionEnded( sectionStats ); + } + + void MultipleReporters::testCaseEnded( TestCaseStats const& testCaseStats ) { + for( auto const& reporter : m_reporters ) + reporter->testCaseEnded( testCaseStats ); + } + + void MultipleReporters::testGroupEnded( TestGroupStats const& testGroupStats ) { + for( auto const& reporter : m_reporters ) + reporter->testGroupEnded( testGroupStats ); + } + + void MultipleReporters::testRunEnded( TestRunStats const& testRunStats ) { + for( auto const& reporter : m_reporters ) + reporter->testRunEnded( testRunStats ); + } + + void MultipleReporters::skipTest( TestCaseInfo const& testInfo ) { + for( auto const& reporter : m_reporters ) + reporter->skipTest( testInfo ); + } + + bool MultipleReporters::isMulti() const { + return true; + } + +} // end namespace Catch +// end catch_reporter_multi.cpp +// start catch_reporter_xml.cpp + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + XmlReporter::XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_xml(_config.stream()) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + XmlReporter::~XmlReporter() = default; + + std::string XmlReporter::getDescription() { + return "Reports test results as an XML document"; + } + + std::string XmlReporter::getStylesheetRef() const { + return std::string(); + } + + void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) { + m_xml + .writeAttribute( "filename", sourceInfo.file ) + .writeAttribute( "line", sourceInfo.line ); + } + + void XmlReporter::noMatchingTestCases( std::string const& s ) { + StreamingReporterBase::noMatchingTestCases( s ); + } + + void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) { + StreamingReporterBase::testRunStarting( testInfo ); + std::string stylesheetRef = getStylesheetRef(); + if( !stylesheetRef.empty() ) + m_xml.writeStylesheetRef( stylesheetRef ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + } + + void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ) + .writeAttribute( "name", trim( testInfo.name ) ) + .writeAttribute( "description", testInfo.description ) + .writeAttribute( "tags", testInfo.tagsAsString() ); + + writeSourceInfo( testInfo.lineInfo ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); + } + + void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ) + .writeAttribute( "description", sectionInfo.description ); + writeSourceInfo( sectionInfo.lineInfo ); + m_xml.ensureTagClosed(); + } + } + + void XmlReporter::assertionStarting( AssertionInfo const& ) { } + + bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) { + + AssertionResult const& result = assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + if( includeResults || result.getResultType() == ResultWas::Warning ) { + // Print any info messages in <Info> tags. + for( auto const& msg : assertionStats.infoMessages ) { + if( msg.type == ResultWas::Info && includeResults ) { + m_xml.scopedElement( "Info" ) + .writeText( msg.message ); + } else if ( msg.type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( msg.message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return true; + + // Print the expression if there is one. + if( result.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", result.succeeded() ) + .writeAttribute( "type", result.getTestMacroName() ); + + writeSourceInfo( result.getSourceInfo() ); + + m_xml.scopedElement( "Original" ) + .writeText( result.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( result.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( result.getResultType() ) { + case ResultWas::ThrewException: + m_xml.startElement( "Exception" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement( "FatalErrorCondition" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( result.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement( "Failure" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + default: + break; + } + + if( result.hasExpression() ) + m_xml.endElement(); + + return true; + } + + void XmlReporter::sectionEnded( SectionStats const& sectionStats ) { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + if( !testCaseStats.stdOut.empty() ) + m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); + if( !testCaseStats.stdErr.empty() ) + m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); + + m_xml.endElement(); + } + + void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_xml.cpp + +namespace Catch { + LeakDetector leakDetector; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_impl.hpp +#endif + +#ifdef CATCH_CONFIG_MAIN +// start catch_default_main.hpp + +#ifndef __OBJC__ + +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) +// Standard C/C++ Win32 Unicode wmain entry point +extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +#else +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { +#endif + + return Catch::Session().run( argc, argv ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char**)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return result; +} + +#endif // __OBJC__ + +// end catch_default_main.hpp +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +#if !defined(CATCH_CONFIG_DISABLE) +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) + +#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) +#endif// CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) + +#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) +#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) + +#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) ) + +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc ) +#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc ) +#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc ) +#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc ) +#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) + +#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) + +#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) +#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) + +#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) +#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) ) + +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) + +#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc ) +#define WHEN( desc ) SECTION( std::string(" When: ") + desc ) +#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc ) +#define THEN( desc ) SECTION( std::string(" Then: ") + desc ) +#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc ) + +using Catch::Detail::Approx; + +#else +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( ... ) (void)(0) +#define CATCH_REQUIRE_FALSE( ... ) (void)(0) + +#define CATCH_REQUIRE_THROWS( ... ) (void)(0) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif// CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0) + +#define CATCH_CHECK( ... ) (void)(0) +#define CATCH_CHECK_FALSE( ... ) (void)(0) +#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__) +#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) +#define CATCH_CHECK_NOFAIL( ... ) (void)(0) + +#define CATCH_CHECK_THROWS( ... ) (void)(0) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW( ... ) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT( arg, matcher ) (void)(0) + +#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO( msg ) (void)(0) +#define CATCH_WARN( msg ) (void)(0) +#define CATCH_CAPTURE( msg ) (void)(0) + +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_METHOD_AS_TEST_CASE( method, ... ) +#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) +#define CATCH_SECTION( ... ) +#define CATCH_FAIL( ... ) (void)(0) +#define CATCH_FAIL_CHECK( ... ) (void)(0) +#define CATCH_SUCCEED( ... ) (void)(0) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define CATCH_GIVEN( desc ) +#define CATCH_WHEN( desc ) +#define CATCH_AND_WHEN( desc ) +#define CATCH_THEN( desc ) +#define CATCH_AND_THEN( desc ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( ... ) (void)(0) +#define REQUIRE_FALSE( ... ) (void)(0) + +#define REQUIRE_THROWS( ... ) (void)(0) +#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) +#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW( ... ) (void)(0) + +#define CHECK( ... ) (void)(0) +#define CHECK_FALSE( ... ) (void)(0) +#define CHECKED_IF( ... ) if (__VA_ARGS__) +#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) +#define CHECK_NOFAIL( ... ) (void)(0) + +#define CHECK_THROWS( ... ) (void)(0) +#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0) +#define CHECK_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW( ... ) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT( arg, matcher ) (void)(0) + +#define REQUIRE_THAT( arg, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO( msg ) (void)(0) +#define WARN( msg ) (void)(0) +#define CAPTURE( msg ) (void)(0) + +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define METHOD_AS_TEST_CASE( method, ... ) +#define REGISTER_TEST_CASE( Function, ... ) (void)(0) +#define SECTION( ... ) +#define FAIL( ... ) (void)(0) +#define FAIL_CHECK( ... ) (void)(0) +#define SUCCEED( ... ) (void)(0) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// "BDD-style" convenience wrappers +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) + +#define GIVEN( desc ) +#define WHEN( desc ) +#define AND_WHEN( desc ) +#define THEN( desc ) +#define AND_THEN( desc ) + +using Catch::Detail::Approx; + +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +// start catch_reenable_warnings.h + + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + +// end catch_reenable_warnings.h +// end catch.hpp +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + diff --git a/test/common/catch_main.cpp b/test/common/catch_main.cpp new file mode 100644 index 0000000..3c3c6f2 --- /dev/null +++ b/test/common/catch_main.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file +#include <catch.hpp> diff --git a/utils/adlmidi-2/9x15.hpp b/utils/adlmidi-2/9x15.hpp index e535d49..76e0660 100644 --- a/utils/adlmidi-2/9x15.hpp +++ b/utils/adlmidi-2/9x15.hpp @@ -160,8 +160,8 @@ struct font9x15: public UIfontBase virtual unsigned GetIndex(char32_t c) const { return ns_font9x15::unicode_to_bitmap_index[c]; } }; -static UIfontBase* Getfont9x15() -{ - static font9x15 f; - return &f; -} +//static UIfontBase* Getfont9x15() +//{ +// static font9x15 f; +// return &f; +//} diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc index b670083..74806eb 100644 --- a/utils/adlmidi-2/midiplay.cc +++ b/utils/adlmidi-2/midiplay.cc @@ -1593,6 +1593,7 @@ int main(int argc, char **argv) UI.Color(7); std::fflush(stderr); std::printf( + "\n\n" "Usage: adlmidi <midifilename> [ <options> ] [ <banknumber> [ <numcards> [ <numfourops>] ] ]\n" " adlmidi <midifilename> -1 To enter instrument tester\n" " -p Enables adlib percussion instrument mode (use with CMF files)\n" @@ -1758,7 +1759,7 @@ int main(int argc, char **argv) if(argc >= 3) { - if(is_number(argv[2])) + if(is_number(argv[2]) || !strcmp(argv[2], "-1")) { int bankno = std::atoi(argv[2]); if(bankno == -1) diff --git a/utils/adlmidi-2/puzzlegame.cc b/utils/adlmidi-2/puzzlegame.cc index e9d2b9b..f8fa57c 100644 --- a/utils/adlmidi-2/puzzlegame.cc +++ b/utils/adlmidi-2/puzzlegame.cc @@ -4,6 +4,8 @@ #include "input.hpp" #include "puzzlegame.hpp" +char ADLMIDI_PuzzleGame::peeked_input = 0; + unsigned long ADLMIDI_PuzzleGame::TimerRead() { static std::chrono::time_point<std::chrono::system_clock> begin = std::chrono::system_clock::now(); diff --git a/utils/adlmidi-2/puzzlegame.hpp b/utils/adlmidi-2/puzzlegame.hpp index 03ad921..a35f1cb 100755 --- a/utils/adlmidi-2/puzzlegame.hpp +++ b/utils/adlmidi-2/puzzlegame.hpp @@ -36,7 +36,7 @@ namespace ADLMIDI_PuzzleGame void Sound(unsigned/*freq*/, unsigned/*duration*/); void PutCell(int x, int y, unsigned cell); void ScreenPutString(const char* str, unsigned attr, unsigned column, unsigned row); - static char peeked_input = 0; + extern char peeked_input; bool kbhit(); char getch(); diff --git a/utils/dumpbank/dumpbank.cpp b/utils/dumpbank/dumpbank.cpp index 84283e7..d2df74a 100644 --- a/utils/dumpbank/dumpbank.cpp +++ b/utils/dumpbank/dumpbank.cpp @@ -190,5 +190,12 @@ static void LoadBNK(const char* fn) int main(int argc, const char* const* argv) { + if(argc < 2) + { + std::printf("Usage: \n" + " %s filename.bnk\n" + "\n", argv[0]); + return 1; + } LoadBNK(argv[1]); } diff --git a/utils/dumpmiles/dumpmiles.cpp b/utils/dumpmiles/dumpmiles.cpp index 0c2d51b..a1a3816 100644 --- a/utils/dumpmiles/dumpmiles.cpp +++ b/utils/dumpmiles/dumpmiles.cpp @@ -49,5 +49,14 @@ static void LoadMiles(const char* fn) int main(int argc, const char* const* argv) { + if(argc < 2) + { + std::printf("Usage: \n" + " %s filename.opl\n" + "or:\n" + " %s filename.opl\n" + "\n", argv[0], argv[0]); + return 1; + } LoadMiles(argv[1]); } diff --git a/utils/gen_adldata/file_formats/load_ail.h b/utils/gen_adldata/file_formats/load_ail.h index a10ff92..e63b1d7 100644 --- a/utils/gen_adldata/file_formats/load_ail.h +++ b/utils/gen_adldata/file_formats/load_ail.h @@ -89,6 +89,7 @@ static bool LoadMiles(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = gmno < 128 ? 0 : (unsigned char)notenum; tmp2.pseudo4op = false; + tmp2.real4op = (inscount > 1); tmp2.voice2_fine_tune = 0.0; std::string name; if(midi_index >= 0) name = std::string(1, '\377') + MidiInsName[midi_index]; diff --git a/utils/gen_adldata/file_formats/load_bisqwit.h b/utils/gen_adldata/file_formats/load_bisqwit.h index 015b0eb..f5f73dc 100644 --- a/utils/gen_adldata/file_formats/load_bisqwit.h +++ b/utils/gen_adldata/file_formats/load_bisqwit.h @@ -44,6 +44,7 @@ static bool LoadBisqwit(const char *fn, unsigned bank, const char *prefix) (gmno < 128 ? 'M' : 'P'), gmno & 127); tmp[1].diff = (tmp[0] != tmp[1]); + tmp2.real4op = tmp[1].diff; size_t resno = InsertIns(tmp[0], tmp[1], tmp2, name, name2, (tmp[0] == tmp[1])); SetBank(bank, gmno, resno); } diff --git a/utils/gen_adldata/file_formats/load_bnk.h b/utils/gen_adldata/file_formats/load_bnk.h index a41185a..aa7701f 100644 --- a/utils/gen_adldata/file_formats/load_bnk.h +++ b/utils/gen_adldata/file_formats/load_bnk.h @@ -69,7 +69,8 @@ static bool LoadBNK(const char *fn, unsigned bank, const char *prefix, bool is_f if(name[2] == 'O' || name[2] == 'S') { - gmno = 128 + std::stoi(name.substr(3)); + std::string n = name.substr(3); + gmno = 128 + std::atoi(n.c_str()); } } @@ -107,6 +108,7 @@ static bool LoadBNK(const char *fn, unsigned bank, const char *prefix, bool is_f ins tmp2; tmp2.notenum = is_fat ? voice_num : (percussive ? usage_flag : 0); tmp2.pseudo4op = false; + tmp2.real4op = false; tmp2.voice2_fine_tune = 0.0; if(is_fat) tmp.data[10] ^= 1; diff --git a/utils/gen_adldata/file_formats/load_bnk2.h b/utils/gen_adldata/file_formats/load_bnk2.h index 1f3d4a1..4772da5 100644 --- a/utils/gen_adldata/file_formats/load_bnk2.h +++ b/utils/gen_adldata/file_formats/load_bnk2.h @@ -3,6 +3,11 @@ #include "../progs_cache.h" +inline int stdstoi(const std::string& str) +{ + return std::atoi(str.c_str()); +} + static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix, const std::string &melo_filter, const std::string &perc_filter) @@ -43,9 +48,9 @@ static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix, int gmno = 0; if(name.substr(0, melo_filter.size()) == melo_filter) - gmno = std::stoi(name.substr(melo_filter.size())); + gmno = stdstoi(name.substr(melo_filter.size())); else if(name.substr(0, perc_filter.size()) == perc_filter) - gmno = std::stoi(name.substr(perc_filter.size())) + 128; + gmno = stdstoi(name.substr(perc_filter.size())) + 128; else continue; @@ -81,6 +86,7 @@ static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix, ins tmp2; tmp2.notenum = (gmno & 128) ? 35 : 0; tmp2.pseudo4op = false; + tmp2.real4op = false; tmp2.voice2_fine_tune = 0.0; if(xxP24NNN & 8) diff --git a/utils/gen_adldata/file_formats/load_ea.h b/utils/gen_adldata/file_formats/load_ea.h index 5e0baa4..79367d9 100644 --- a/utils/gen_adldata/file_formats/load_ea.h +++ b/utils/gen_adldata/file_formats/load_ea.h @@ -85,16 +85,17 @@ static bool LoadEA(const char *fn, unsigned bank, const char *prefix) ins tmp2{}; tmp2.notenum = 0; tmp2.pseudo4op = false; + tmp2.real4op = false; std::string name; char name2[512]; if(gmno < 20) { - std::snprintf(name2, 512, "%sM%u", prefix, gmno); + snprintf(name2, 512, "%sM%u", prefix, gmno); } else { - std::snprintf(name2, 512, "%sunk%04X", prefix, offset); + snprintf(name2, 512, "%sunk%04X", prefix, offset); } size_t resno = InsertIns(tmp, tmp2, std::string(1, '\377') + name, name2); SetBank(bank, gmno, resno); diff --git a/utils/gen_adldata/file_formats/load_ibk.h b/utils/gen_adldata/file_formats/load_ibk.h index bc03962..12fa520 100644 --- a/utils/gen_adldata/file_formats/load_ibk.h +++ b/utils/gen_adldata/file_formats/load_ibk.h @@ -61,6 +61,7 @@ static bool LoadIBK(const char *fn, unsigned bank, const char *prefix, bool perc struct ins tmp2; tmp2.notenum = gmno < 128 ? 0 : 35; tmp2.pseudo4op = false; + tmp2.real4op = false; tmp2.voice2_fine_tune = 0.0; size_t resno = InsertIns(tmp, tmp2, std::string(1, '\377') + name, name2); diff --git a/utils/gen_adldata/file_formats/load_jv.h b/utils/gen_adldata/file_formats/load_jv.h index b79832f..35caead 100644 --- a/utils/gen_adldata/file_formats/load_jv.h +++ b/utils/gen_adldata/file_formats/load_jv.h @@ -71,6 +71,7 @@ static bool LoadJunglevision(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = data[offset + 1]; tmp2.pseudo4op = false; + tmp2.real4op = (data[offset] != 0); tmp2.voice2_fine_tune = 0.0; while(tmp2.notenum && tmp2.notenum < 20) diff --git a/utils/gen_adldata/file_formats/load_op2.h b/utils/gen_adldata/file_formats/load_op2.h index 8b7fec6..48b7eae 100644 --- a/utils/gen_adldata/file_formats/load_op2.h +++ b/utils/gen_adldata/file_formats/load_op2.h @@ -82,7 +82,7 @@ static bool LoadDoom(const char *fn, unsigned bank, const char *prefix) int gmno = int(a < 128 ? a : ((a | 128) + 35)); char name2[512]; - std::snprintf(name2, 512, "%s%c%u", prefix, (gmno < 128 ? 'M' : 'P'), gmno & 127); + snprintf(name2, 512, "%s%c%u", prefix, (gmno < 128 ? 'M' : 'P'), gmno & 127); Doom_opl_instr &ins = *(Doom_opl_instr *) &data[offset2]; @@ -108,6 +108,7 @@ static bool LoadDoom(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = ins.note; tmp2.pseudo4op = false; + tmp2.real4op = false; tmp2.voice2_fine_tune = 0.0; while(tmp2.notenum && tmp2.notenum < 20) { diff --git a/utils/gen_adldata/file_formats/load_tmb.h b/utils/gen_adldata/file_formats/load_tmb.h index ab1ff37..5b38433 100644 --- a/utils/gen_adldata/file_formats/load_tmb.h +++ b/utils/gen_adldata/file_formats/load_tmb.h @@ -50,6 +50,7 @@ static bool LoadTMB(const char *fn, unsigned bank, const char *prefix) struct ins tmp2; tmp2.notenum = data[offset + 11]; tmp2.pseudo4op = false; + tmp2.real4op = false; tmp2.voice2_fine_tune = 0.0; std::string name; diff --git a/utils/gen_adldata/file_formats/load_wopl.h b/utils/gen_adldata/file_formats/load_wopl.h index 26a2611..fe4865d 100644 --- a/utils/gen_adldata/file_formats/load_wopl.h +++ b/utils/gen_adldata/file_formats/load_wopl.h @@ -57,8 +57,8 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix) uint16_t pbanks_count = toUint16BE((const uint8_t *)data.data() + 0x0f); AdlBankSetup setup; - setup.deepTremolo = (data[0x11] >> 0) & 0x01; - setup.deepVibrato = (data[0x11] >> 1) & 0x01; + setup.deepTremolo = (data[0x11] & 0x01) != 0; + setup.deepVibrato = (data[0x11] & 0x02) != 0; setup.volumeModel = (int)data[0x12]; setup.adLibPercussions = false; setup.scaleModulators = false; @@ -169,6 +169,7 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix) tmp2.notenum = is_percussion ? data[offset + 38] : 0; bool real4op = (flags & (uint8_t)WOPL_Flags::Mode_4op) != 0; tmp2.pseudo4op = (flags & (uint8_t)WOPL_Flags::Mode_DoubleVoice) != 0; + tmp2.real4op = real4op && !tmp2.pseudo4op; tmp2.voice2_fine_tune = 0; tmp[0].diff = false; tmp[1].diff = real4op && !tmp2.pseudo4op; @@ -207,9 +208,9 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix) char name2[512]; std::memset(name2, 0, 512); if(is_percussion) - std::snprintf(name2, 512, "%sP%u", prefix, gmno & 127); + snprintf(name2, 512, "%sP%u", prefix, gmno & 127); else - std::snprintf(name2, 512, "%sM%u", prefix, i); + snprintf(name2, 512, "%sM%u", prefix, i); if(!real4op && !tmp2.pseudo4op) { diff --git a/utils/gen_adldata/gen_adldata.cc b/utils/gen_adldata/gen_adldata.cc index 7c8af8b..bc5c231 100644 --- a/utils/gen_adldata/gen_adldata.cc +++ b/utils/gen_adldata/gen_adldata.cc @@ -312,7 +312,7 @@ int main(int argc, char**argv) i->first.data[10], i->first.finetune); - #ifdef ADLDATA_WITH_COMMENTS +#ifdef ADLDATA_WITH_COMMENTS std::string names; for(std::set<std::string>::const_iterator j = i->second.second.begin(); @@ -326,9 +326,9 @@ int main(int argc, char**argv) names += *j; } std::fprintf(outFile, " }, // %u: %s\n", (unsigned)c, names.c_str()); - #else +#else std::fprintf(outFile, " },\n"); - #endif +#endif } } std::fprintf(outFile, "};\n"); @@ -341,6 +341,7 @@ int main(int argc, char**argv) " unsigned char flags;\n" " long ms_sound_kon; // Number of milliseconds it produces sound;\n" " long ms_sound_koff;\n" + " double voice2_fine_tune;\n" "} adlins[] =\n");*/ std::fprintf(outFile, "const struct adlinsdata adlins[%u] =\n", (unsigned)instab.size()); @@ -348,7 +349,7 @@ int main(int argc, char**argv) MeasureThreaded measureCounter; { - std::printf("Beginning to generate measures data... (Hardware concurrency: %d)\n", std::thread::hardware_concurrency()); + std::printf("Beginning to generate measures data... (hardware concurrency of %d)\n", std::thread::hardware_concurrency()); std::fflush(stdout); measureCounter.LoadCache("fm_banks/adldata-cache.dat"); measureCounter.m_total = instab.size(); @@ -381,7 +382,7 @@ int main(int argc, char**argv) //DurationInfo info = MeasureDurations(i->first); MeasureThreaded::DurationInfoCache::iterator indo_i = measureCounter.m_durationInfo.find(i->first); DurationInfo info = indo_i->second; - #ifdef ADLDATA_WITH_COMMENTS +#ifdef ADLDATA_WITH_COMMENTS { if(info.peak_amplitude_time == 0) { @@ -404,12 +405,14 @@ int main(int argc, char**argv) info.keyoff_out_time / double(info.interval)); } } - #endif +#endif - unsigned flags = (i->first.pseudo4op ? 1 : 0) | (info.nosound ? 2 : 0); + unsigned flags = (i->first.pseudo4op ? ins::Flag_Pseudo4op : 0)| + (i->first.real4op ? ins::Flag_Real4op : 0) | + (info.nosound ? ins::Flag_NoSound : 0); std::fprintf(outFile, " {"); - std::fprintf(outFile, "%4d,%4d,%3d, %d, %6" PRId64 ",%6" PRId64 ",%lf", + std::fprintf(outFile, "%4d,%4d,%3d, %d, %6" PRId64 ",%6" PRId64 ",%g", (unsigned) i->first.insno1, (unsigned) i->first.insno2, (int)(i->first.notenum), @@ -429,11 +432,11 @@ int main(int argc, char**argv) else names += *j; } - #ifdef ADLDATA_WITH_COMMENTS +#ifdef ADLDATA_WITH_COMMENTS std::fprintf(outFile, " }, // %u: %s\n\n", (unsigned)c, names.c_str()); - #else +#else std::fprintf(outFile, " },\n"); - #endif +#endif std::fflush(outFile); adlins_flags.push_back(flags); } @@ -444,11 +447,11 @@ int main(int argc, char**argv) std::fflush(stdout); //fprintf(outFile, "static const unsigned short banks[][256] =\n"); - #ifdef HARD_BANKS +#ifdef HARD_BANKS const unsigned bankcount = sizeof(banknames) / sizeof(*banknames); - #else +#else const size_t bankcount = banknames.size(); - #endif +#endif size_t nosound = InsertNoSoundIns(); @@ -486,25 +489,29 @@ int main(int argc, char**argv) std::fprintf(outFile, "{\n"); for(unsigned bank = 0; bank < bankcount; ++bank) { - #ifdef ADLDATA_WITH_COMMENTS +#ifdef ADLDATA_WITH_COMMENTS std::fprintf(outFile, " { // bank %u, %s\n", bank, banknames[bank].c_str()); - #else +#else std::fprintf(outFile, " {\n"); #endif +#ifdef ADLDATA_WITH_COMMENTS bool redundant = true; +#endif for(unsigned p = 0; p < 256; ++p) { size_t v = bank_data[bank][p]; if(listed.find(v) == listed.end()) { listed.insert(v); +#ifdef ADLDATA_WITH_COMMENTS redundant = false; +#endif } std::fprintf(outFile, "%4d,", (unsigned int)v); if(p % 16 == 15) fprintf(outFile, "\n"); } std::fprintf(outFile, " },\n"); - #ifdef ADLDATA_WITH_COMMENTS +#ifdef ADLDATA_WITH_COMMENTS if(redundant) { std::fprintf(outFile, " // Bank %u defines nothing new.\n", bank); @@ -523,7 +530,7 @@ int main(int argc, char**argv) bank, refbank); } } - #endif +#endif } std::fprintf(outFile, "};\n\n"); diff --git a/utils/gen_adldata/ini/ini_processing.cpp b/utils/gen_adldata/ini/ini_processing.cpp index 26da540..8a2807b 100644 --- a/utils/gen_adldata/ini/ini_processing.cpp +++ b/utils/gen_adldata/ini/ini_processing.cpp @@ -1,27 +1,26 @@ /* -INI Processor - a small library which allows you parsing INI-files - -Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ + * INI Processor - a small library which allows you parsing INI-files + * + * Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ //#define USE_FILE_MAPPER diff --git a/utils/gen_adldata/ini/ini_processing.h b/utils/gen_adldata/ini/ini_processing.h index 8da4b7e..64777a5 100644 --- a/utils/gen_adldata/ini/ini_processing.h +++ b/utils/gen_adldata/ini/ini_processing.h @@ -1,26 +1,26 @@ /* -INI Processor - a small library which allows you parsing INI-files - -Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ + * INI Processor - a small library which allows you parsing INI-files + * + * Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #ifndef INIPROCESSING_H #define INIPROCESSING_H diff --git a/utils/gen_adldata/ini/ini_processing_variant.h b/utils/gen_adldata/ini/ini_processing_variant.h index 41a96dd..d659aa9 100644 --- a/utils/gen_adldata/ini/ini_processing_variant.h +++ b/utils/gen_adldata/ini/ini_processing_variant.h @@ -1,31 +1,31 @@ /* -INI Processor - a small library which allows you parsing INI-files - -Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ + * INI Processor - a small library which allows you parsing INI-files + * + * Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ /* -A QVariant-like thing created just like a proxy between -INI Processor and target value (to be compatible with QSettings) -*/ + * A QVariant-like thing created just like a proxy between + * INI Processor and target value (to be compatible with QSettings) + */ #ifndef INI_PROCESSING_VARIANT_H #define INI_PROCESSING_VARIANT_H diff --git a/utils/gen_adldata/measurer.cpp b/utils/gen_adldata/measurer.cpp index 7a81379..7caf883 100644 --- a/utils/gen_adldata/measurer.cpp +++ b/utils/gen_adldata/measurer.cpp @@ -1,7 +1,9 @@ #include "measurer.h" #include <cmath> -#include "../../src/chips/opl_chip_base.h" +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif // Nuked OPL3 emulator, Most accurate, but requires the powerful CPU #ifndef ADLMIDI_DISABLE_NUKED_EMULATOR @@ -14,208 +16,367 @@ # include "../../src/chips/dosbox_opl3.h" #endif -DurationInfo MeasureDurations(const ins &in) +template <class T> +class AudioHistory { - std::vector<int16_t> stereoSampleBuf; -#ifdef ADLMIDI_USE_DOSBOX_OPL - std::vector<int32_t> stereoSampleBuf_32; -#endif - insdata id[2]; - bool found[2] = {false, false}; - for(InstrumentDataTab::const_iterator j = insdatatab.begin(); - j != insdatatab.end(); - ++j) + std::unique_ptr<T[]> m_data; + size_t m_index = 0; // points to the next write slot + size_t m_length = 0; + size_t m_capacity = 0; + +public: + size_t size() const { return m_length; } + size_t capacity() const { return m_capacity; } + const T *data() const { return &m_data[m_index + m_capacity - m_length]; } + + void reset(size_t capacity) { - if(j->second.first == in.insno1) - { - id[0] = j->first; - found[0] = true; - if(found[1]) break; - } - if(j->second.first == in.insno2) - { - id[1] = j->first; - found[1] = true; - if(found[0]) break; - } + m_data.reset(new T[2 * capacity]()); + m_index = 0; + m_length = 0; + m_capacity = capacity; } - const unsigned rate = 22010; - const unsigned interval = 150; - const unsigned samples_per_interval = rate / interval; - const int notenum = - in.notenum < 20 ? (44 + in.notenum) - : in.notenum >= 128 ? (44 + 128 - in.notenum) - : in.notenum; - OPLChipBase *opl; + void clear() + { + m_length = 0; + } - //DosBoxOPL3 db; opl = &db; - //NukedOPL3 nuke; opl = &nuke; - NukedOPL3v174 nuke74; opl = &nuke74; + void add(const T &item) + { + T *data = m_data.get(); + const size_t capacity = m_capacity; + size_t index = m_index; + data[index] = item; + data[index + capacity] = item; + m_index = (index + 1 != capacity) ? (index + 1) : 0; + size_t length = m_length + 1; + m_length = (length < capacity) ? length : capacity; + } +}; -#define WRITE_REG(key, value) opl->writeReg((uint16_t)(key), (uint8_t)(value)) +static void HannWindow(double *w, unsigned n) +{ + for (unsigned i = 0; i < n; ++i) + w[i] = 0.5 * (1.0 - std::cos(2 * M_PI * i / (n - 1))); +} - static const short initdata[(2 + 3 + 2 + 2) * 2] = +static double MeasureRMS(const double *signal, const double *window, unsigned length) +{ + double mean = 0; +#pragma omp simd reduction(+: mean) + for(unsigned i = 0; i < length; ++i) + mean += window[i] * signal[i]; + mean /= length; + + double rms = 0; +#pragma omp simd reduction(+: rms) + for(unsigned i = 0; i < length; ++i) { - 0x004, 96, 0x004, 128, // Pulse timer - 0x105, 0, 0x105, 1, 0x105, 0, // Pulse OPL3 enable, leave disabled - 0x001, 32, 0x0BD, 0 // Enable wave & melodic - }; - opl->setRate(rate); + double diff = window[i] * signal[i] - mean; + rms += diff * diff; + } + rms = std::sqrt(rms / (length - 1)); - for(unsigned a = 0; a < 18; a += 2) WRITE_REG(initdata[a], initdata[a + 1]); + return rms; +} - const unsigned n_notes = in.insno1 == in.insno2 ? 1 : 2; - unsigned x[2]; +static const unsigned g_outputRate = 49716; - if(n_notes == 2 && !in.pseudo4op) +struct TinySynth +{ + OPLChipBase *m_chip; + unsigned m_notesNum; + int m_notenum; + int8_t m_fineTune; + int16_t m_noteOffsets[2]; + unsigned m_x[2]; + + void resetChip() { - WRITE_REG(0x105, 1); - WRITE_REG(0x104, 1); - } + static const short initdata[(2 + 3 + 2 + 2) * 2] = + { + 0x004, 96, 0x004, 128, // Pulse timer + 0x105, 0, 0x105, 1, 0x105, 0, // Pulse OPL3 enable, leave disabled + 0x001, 32, 0x0BD, 0 // Enable wave & melodic + }; - for(unsigned n = 0; n < n_notes; ++n) - { - static const unsigned char patchdata[11] = - {0x20, 0x23, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0x40, 0x43, 0xC0}; - for(unsigned a = 0; a < 10; ++a) WRITE_REG(patchdata[a] + n * 8, id[n].data[a]); - WRITE_REG(patchdata[10] + n * 8, id[n].data[10] | 0x30); + m_chip->setRate(g_outputRate); + + for(unsigned a = 0; a < 18; a += 2) + m_chip->writeReg((uint16_t)initdata[a], (uint8_t)initdata[a + 1]); } - for(unsigned n = 0; n < n_notes; ++n) + void setInstrument(const ins &in) { - double hertz = 172.00093 * std::exp(0.057762265 * (notenum + id[n].finetune)); - if(hertz > 131071) + insdata rawData[2]; + bool found[2] = {false, false}; + for(InstrumentDataTab::const_iterator j = insdatatab.begin(); + j != insdatatab.end(); + ++j) + { + if(j->second.first == in.insno1) + { + rawData[0] = j->first; + found[0] = true; + if(found[1]) break; + } + if(j->second.first == in.insno2) + { + rawData[1] = j->first; + found[1] = true; + if(found[0]) break; + } + } + + std::memset(m_x, 0, sizeof(m_x)); + m_notenum = in.notenum >= 128 ? (in.notenum - 128) : in.notenum; + if(m_notenum == 0) + m_notenum = 25; + m_notesNum = in.insno1 == in.insno2 ? 1 : 2; + m_fineTune = 0; + m_noteOffsets[0] = rawData[0].finetune; + m_noteOffsets[1] = rawData[1].finetune; + if(in.pseudo4op) + m_fineTune = in.voice2_fine_tune; + if(in.real4op) { - std::fprintf(stderr, "MEASURER WARNING: Why does note %d + finetune %d produce hertz %g? \n", - notenum, id[n].finetune, hertz); - hertz = 131071; + m_chip->writeReg(0x105, 1); + m_chip->writeReg(0x104, 0xFF); } - x[n] = 0x2000; - while(hertz >= 1023.5) + + //For clearer measurement, disable tremolo and vibrato + rawData[0].data[0] &= 0x3F; + rawData[0].data[1] &= 0x3F; + rawData[1].data[0] &= 0x3F; + rawData[1].data[1] &= 0x3F; + + for(unsigned n = 0; n < m_notesNum; ++n) { - hertz /= 2.0; // Calculate octave - x[n] += 0x400; + static const unsigned char patchdata[11] = + {0x20, 0x23, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0x40, 0x43, 0xC0}; + for(unsigned a = 0; a < 10; ++a) + m_chip->writeReg(patchdata[a] + n * 8, rawData[n].data[a]); + m_chip->writeReg(patchdata[10] + n * 8, rawData[n].data[10] | 0x30); } - x[n] += (unsigned int)(hertz + 0.5); + } + + void noteOn() + { + std::memset(m_x, 0, sizeof(m_x)); + for(unsigned n = 0; n < m_notesNum; ++n) + { + double hertz = 172.00093 * std::exp(0.057762265 * (m_notenum + m_noteOffsets[n])); + if(hertz > 131071) + { + std::fprintf(stdout, "%s:%d:0: warning: Why does note %d + note-offset %d produce hertz %g?\n", __FILE__, __LINE__, + m_notenum, m_noteOffsets[n], hertz); + std::fflush(stdout); + hertz = 131071; + } + m_x[n] = 0x2000; + while(hertz >= 1023.5) + { + hertz /= 2.0; // Calculate octave + m_x[n] += 0x400; + } + m_x[n] += (unsigned int)(hertz + 0.5); - // Keyon the note - WRITE_REG(0xA0 + n * 3, x[n] & 0xFF); - WRITE_REG(0xB0 + n * 3, x[n] >> 8); + // Keyon the note + m_chip->writeReg(0xA0 + n * 3, m_x[n] & 0xFF); + m_chip->writeReg(0xB0 + n * 3, m_x[n] >> 8); + } + } + + void noteOff() + { + // Keyoff the note + for(unsigned n = 0; n < m_notesNum; ++n) + m_chip->writeReg(0xB0 + n * 3, (m_x[n] >> 8) & 0xDF); } + void generate(int16_t *output, size_t frames) + { + m_chip->generate(output, frames); + } +}; + + +DurationInfo MeasureDurations(const ins &in, OPLChipBase *chip) +{ + AudioHistory<double> audioHistory; + + const unsigned interval = 150; + const unsigned samples_per_interval = g_outputRate / interval; + + const double historyLength = 0.1; // maximum duration to memorize (seconds) + audioHistory.reset(std::ceil(historyLength * g_outputRate)); + + std::unique_ptr<double[]> window; + window.reset(new double[audioHistory.capacity()]); + unsigned winsize = 0; + + TinySynth synth; + synth.m_chip = chip; + synth.resetChip(); + synth.setInstrument(in); + synth.noteOn(); + + /* For capturing */ const unsigned max_silent = 6; const unsigned max_on = 40; const unsigned max_off = 60; + unsigned max_period_on = max_on * interval; + unsigned max_period_off = max_off * interval; + + const double min_coefficient_on = 0.008; + const double min_coefficient_off = 0.2; + + unsigned windows_passed_on = 0; + unsigned windows_passed_off = 0; + + /* For Analyze the results */ + double begin_amplitude = 0; + double peak_amplitude_value = 0; + size_t peak_amplitude_time = 0; + size_t quarter_amplitude_time = max_period_on; + bool quarter_amplitude_time_found = false; + size_t keyoff_out_time = 0; + bool keyoff_out_time_found = false; + + const size_t audioBufferLength = 256; + const size_t audioBufferSize = 2 * audioBufferLength; + int16_t audioBuffer[audioBufferSize]; + // For up to 40 seconds, measure mean amplitude. - std::vector<double> amplitudecurve_on; double highest_sofar = 0; short sound_min = 0, sound_max = 0; - for(unsigned period = 0; period < max_on * interval; ++period) + + for(unsigned period = 0; period < max_period_on; ++period, ++windows_passed_on) { - stereoSampleBuf.clear(); - stereoSampleBuf.resize(samples_per_interval * 2); - opl->generate(stereoSampleBuf.data(), samples_per_interval); + for(unsigned i = 0; i < samples_per_interval;) + { + size_t blocksize = samples_per_interval - i; + blocksize = (blocksize < audioBufferLength) ? blocksize : audioBufferLength; + synth.generate(audioBuffer, blocksize); + for (unsigned j = 0; j < blocksize; ++j) + { + int16_t s = audioBuffer[2 * j]; + audioHistory.add(s); + if(sound_min > s) sound_min = s; + if(sound_max < s) sound_max = s; + } + i += blocksize; + } - double mean = 0.0; - for(unsigned long c = 0; c < samples_per_interval; ++c) + if(winsize != audioHistory.size()) { - short s = stereoSampleBuf[c * 2]; - mean += s; - if(sound_min > s) sound_min = s; - if(sound_max < s) sound_max = s; + winsize = audioHistory.size(); + HannWindow(window.get(), winsize); } - mean /= samples_per_interval; - double std_deviation = 0; - for(unsigned long c = 0; c < samples_per_interval; ++c) + + double rms = MeasureRMS(audioHistory.data(), window.get(), winsize); + /* ======== Peak time detection ======== */ + if(period == 0) + { + begin_amplitude = rms; + peak_amplitude_value = rms; + peak_amplitude_time = 0; + } + else if(rms > peak_amplitude_value) { - double diff = (stereoSampleBuf[c * 2] - mean); - std_deviation += diff * diff; + peak_amplitude_value = rms; + peak_amplitude_time = period; + // In next step, update the quater amplitude time + quarter_amplitude_time_found = false; } - std_deviation = std::sqrt(std_deviation / samples_per_interval); - amplitudecurve_on.push_back(std_deviation); - if(std_deviation > highest_sofar) - highest_sofar = std_deviation; + else if(!quarter_amplitude_time_found && (rms <= peak_amplitude_value * min_coefficient_on)) + { + quarter_amplitude_time = period; + quarter_amplitude_time_found = true; + } + /* ======== Peak time detection =END==== */ + if(rms > highest_sofar) + highest_sofar = rms; if((period > max_silent * interval) && - ((std_deviation < highest_sofar * 0.2)|| - (sound_min >= -1 && sound_max <= 1)) + ( (rms < highest_sofar * min_coefficient_on) || (sound_min >= -1 && sound_max <= 1) ) ) break; } - // Keyoff the note - for(unsigned n = 0; n < n_notes; ++n) - WRITE_REG(0xB0 + n * 3, (x[n] >> 8) & 0xDF); + if(!quarter_amplitude_time_found) + quarter_amplitude_time = windows_passed_on; - // Now, for up to 60 seconds, measure mean amplitude. - std::vector<double> amplitudecurve_off; - for(unsigned period = 0; period < max_off * interval; ++period) + if(windows_passed_on >= max_period_on) { - stereoSampleBuf.clear(); - stereoSampleBuf.resize(samples_per_interval * 2); - opl->generate(stereoSampleBuf.data(), samples_per_interval); - - double mean = 0.0; - for(unsigned long c = 0; c < samples_per_interval; ++c) - { - short s = stereoSampleBuf[c * 2]; - mean += s; - if(sound_min > s) sound_min = s; - if(sound_max < s) sound_max = s; - } - mean /= samples_per_interval; - double std_deviation = 0; - for(unsigned long c = 0; c < samples_per_interval; ++c) + // Just Keyoff the note + synth.noteOff(); + } + else + { + // Reset the emulator and re-run the "ON" simulation until reaching the peak time + synth.resetChip(); + synth.setInstrument(in); + synth.noteOn(); + + audioHistory.reset(std::ceil(historyLength * g_outputRate)); + for(unsigned period = 0; + (period < peak_amplitude_time) && (period < max_period_on); + ++period) { - double diff = (stereoSampleBuf[c * 2] - mean); - std_deviation += diff * diff; + for(unsigned i = 0; i < samples_per_interval;) + { + size_t blocksize = samples_per_interval - i; + blocksize = (blocksize < audioBufferLength) ? blocksize : audioBufferLength; + synth.generate(audioBuffer, blocksize); + for (unsigned j = 0; j < blocksize; ++j) + audioHistory.add(audioBuffer[2 * j]); + i += blocksize; + } } - std_deviation = std::sqrt(std_deviation / samples_per_interval); - amplitudecurve_off.push_back(std_deviation); - - if(std_deviation < highest_sofar * 0.2) - break; - - if((period > max_silent * interval) && (sound_min >= -1 && sound_max <= 1)) - break; + synth.noteOff(); } - /* Analyze the results */ - double begin_amplitude = amplitudecurve_on[0]; - double peak_amplitude_value = begin_amplitude; - size_t peak_amplitude_time = 0; - size_t quarter_amplitude_time = amplitudecurve_on.size(); - size_t keyoff_out_time = 0; - - for(size_t a = 1; a < amplitudecurve_on.size(); ++a) + // Now, for up to 60 seconds, measure mean amplitude. + for(unsigned period = 0; period < max_period_off; ++period, ++windows_passed_off) { - if(amplitudecurve_on[a] > peak_amplitude_value) + for(unsigned i = 0; i < samples_per_interval;) { - peak_amplitude_value = amplitudecurve_on[a]; - peak_amplitude_time = a; + size_t blocksize = samples_per_interval - i; + blocksize = (blocksize < 256) ? blocksize : 256; + synth.generate(audioBuffer, blocksize); + for (unsigned j = 0; j < blocksize; ++j) + { + int16_t s = audioBuffer[2 * j]; + audioHistory.add(s); + if(sound_min > s) sound_min = s; + if(sound_max < s) sound_max = s; + } + i += blocksize; } - } - for(size_t a = peak_amplitude_time; a < amplitudecurve_on.size(); ++a) - { - if(amplitudecurve_on[a] <= peak_amplitude_value * 0.2) + + if(winsize != audioHistory.size()) { - quarter_amplitude_time = a; - break; + winsize = audioHistory.size(); + HannWindow(window.get(), winsize); } - } - for(size_t a = 0; a < amplitudecurve_off.size(); ++a) - { - if(amplitudecurve_off[a] <= peak_amplitude_value * 0.2) + + double rms = MeasureRMS(audioHistory.data(), window.get(), winsize); + /* ======== Find Key Off time ======== */ + if(!keyoff_out_time_found && (rms <= peak_amplitude_value * min_coefficient_off)) { - keyoff_out_time = a; - break; + keyoff_out_time = period; + keyoff_out_time_found = true; } - } + /* ======== Find Key Off time ==END=== */ + if(rms < highest_sofar * min_coefficient_off) + break; - if(keyoff_out_time == 0 && amplitudecurve_on.back() < peak_amplitude_value * 0.2) - keyoff_out_time = quarter_amplitude_time; + if((period > max_silent * interval) && (sound_min >= -1 && sound_max <= 1)) + break; + } DurationInfo result; result.peak_amplitude_time = peak_amplitude_time; @@ -227,11 +388,10 @@ DurationInfo MeasureDurations(const ins &in) result.ms_sound_kon = (int64_t)(quarter_amplitude_time * 1000.0 / interval); result.ms_sound_koff = (int64_t)(keyoff_out_time * 1000.0 / interval); result.nosound = (peak_amplitude_value < 0.5) || ((sound_min >= -1) && (sound_max <= 1)); + return result; } -static const char* spinner = "-\\|/"; - void MeasureThreaded::LoadCache(const char *fileName) { FILE *in = std::fopen(fileName, "rb"); @@ -290,6 +450,8 @@ void MeasureThreaded::LoadCache(const char *fileName) inst.insno2 = inval; if(std::fread(&inst.notenum, 1, 1, in) != 1) break; + if(std::fread(&inst.real4op, 1, 1, in) != 1) + break; if(std::fread(&inst.pseudo4op, 1, 1, in) != 1) break; if(std::fread(&inst.voice2_fine_tune, sizeof(double), 1, in) != 1) @@ -418,6 +580,7 @@ void MeasureThreaded::SaveCache(const char *fileName) outval = in.insno2; fwrite(&outval, 1, sizeof(uint64_t), out); fwrite(&in.notenum, 1, 1, out); + fwrite(&in.real4op, 1, 1, out); fwrite(&in.pseudo4op, 1, 1, out); fwrite(&in.voice2_fine_tune, sizeof(double), 1, out); @@ -458,9 +621,13 @@ void MeasureThreaded::SaveCache(const char *fileName) std::fclose(out); } +#ifdef ADL_GENDATA_PRINT_PROGRESS + +static const char* spinner = "-\\|/"; + void MeasureThreaded::printProgress() { - std::printf("Calculating measures... [%c %3u%% (%4u/%4u) Threads %3u, Matches %u] \r", + std::printf("Calculating measures... [%c %3u%% {%4u/%4u} Threads %3u, Matches %u] \r", spinner[m_done.load() % 4], (unsigned int)(((double)m_done.load() / (double)(m_total)) * 100), (unsigned int)m_done.load(), @@ -470,6 +637,12 @@ void MeasureThreaded::printProgress() ); std::fflush(stdout); } +#else +void MeasureThreaded::printProgress() +{ + //Do nothing +} +#endif void MeasureThreaded::printFinal() { @@ -501,14 +674,18 @@ void MeasureThreaded::run(InstrumentsData::const_iterator i) dd->myself = this; dd->start(); m_threads.push_back(dd); +#ifdef ADL_GENDATA_PRINT_PROGRESS printProgress(); +#endif } void MeasureThreaded::waitAll() { for(auto &th : m_threads) { +#ifdef ADL_GENDATA_PRINT_PROGRESS printProgress(); +#endif delete th; } m_threads.clear(); @@ -524,6 +701,7 @@ void MeasureThreaded::destData::callback(void *myself) { destData *s = reinterpret_cast<destData *>(myself); DurationInfo info; + DosBoxOPL3 dosbox; DurationInfoCache::iterator cachedEntry = s->myself->m_durationInfo.find(s->i->first); if(cachedEntry != s->myself->m_durationInfo.end()) @@ -532,7 +710,7 @@ void MeasureThreaded::destData::callback(void *myself) goto endWork; } - info = MeasureDurations(s->i->first); + info = MeasureDurations(s->i->first, &dosbox); s->myself->m_durationInfo_mx.lock(); s->myself->m_durationInfo.insert({s->i->first, info}); s->myself->m_durationInfo_mx.unlock(); diff --git a/utils/gen_adldata/measurer.h b/utils/gen_adldata/measurer.h index b9ae3c6..63475ca 100644 --- a/utils/gen_adldata/measurer.h +++ b/utils/gen_adldata/measurer.h @@ -100,6 +100,7 @@ struct MeasureThreaded void waitAll(); }; -extern DurationInfo MeasureDurations(const ins &in); +class OPLChipBase; +extern DurationInfo MeasureDurations(const ins &in, OPLChipBase *chip); #endif // MEASURER_H diff --git a/utils/gen_adldata/progs_cache.cpp b/utils/gen_adldata/progs_cache.cpp index a59e7b7..81bba4c 100644 --- a/utils/gen_adldata/progs_cache.cpp +++ b/utils/gen_adldata/progs_cache.cpp @@ -112,7 +112,7 @@ size_t InsertNoSoundIns() { // { 0x0F70700,0x0F70710, 0xFF,0xFF, 0x0,+0 }, insdata tmp1 = MakeNoSoundIns(); - struct ins tmp2 = { 0, 0, 0, false, 0.0 }; + struct ins tmp2 = { 0, 0, 0, false, false, 0.0 }; return InsertIns(tmp1, tmp1, tmp2, "nosound", ""); } diff --git a/utils/gen_adldata/progs_cache.h b/utils/gen_adldata/progs_cache.h index 7b4cd39..5a916f5 100644 --- a/utils/gen_adldata/progs_cache.h +++ b/utils/gen_adldata/progs_cache.h @@ -49,9 +49,11 @@ inline bool equal_approx(double const a, double const b) struct ins { + enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02, Flag_Real4op = 0x04 }; size_t insno1, insno2; unsigned char notenum; bool pseudo4op; + bool real4op; double voice2_fine_tune; bool operator==(const ins &b) const @@ -60,6 +62,7 @@ struct ins && insno1 == b.insno1 && insno2 == b.insno2 && pseudo4op == b.pseudo4op + && real4op == b.real4op && equal_approx(voice2_fine_tune, b.voice2_fine_tune); } bool operator< (const ins &b) const @@ -68,6 +71,7 @@ struct ins if(insno2 != b.insno2) return insno2 < b.insno2; if(notenum != b.notenum) return notenum < b.notenum; if(pseudo4op != b.pseudo4op) return pseudo4op < b.pseudo4op; + if(real4op != b.real4op) return real4op < b.real4op; if(!equal_approx(voice2_fine_tune, b.voice2_fine_tune)) return voice2_fine_tune < b.voice2_fine_tune; return 0; } diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp index a591626..8bffc50 100644 --- a/utils/midiplay/adlmidiplay.cpp +++ b/utils/midiplay/adlmidiplay.cpp @@ -320,6 +320,8 @@ int main(int argc, char **argv) #endif #ifndef HARDWARE_OPL3 int emulator = ADLMIDI_EMU_NUKED; + #endif + #if !defined(HARDWARE_OPL3) && !defined(OUTPUT_WAVE_ONLY) g_audioFormat.type = ADLMIDI_SampleType_S16; g_audioFormat.containerSize = sizeof(Sint16); g_audioFormat.sampleOffset = sizeof(Sint16) * 2; @@ -334,7 +336,7 @@ int main(int argc, char **argv) else if(!std::strcmp("-v", argv[2])) adl_setHVibrato(myDevice, 1);//Force turn on deep vibrato - #ifndef OUTPUT_WAVE_ONLY + #if !defined(OUTPUT_WAVE_ONLY) && !defined(HARDWARE_OPL3) else if(!std::strcmp("-w", argv[2])) { //Current Wave output implementation allows only SINT16 output @@ -402,6 +404,7 @@ int main(int argc, char **argv) adl_switchEmulator(myDevice, emulator); #endif + std::fprintf(stdout, " - Library version %s\n", adl_linkedLibraryVersion()); #ifdef HARDWARE_OPL3 std::fprintf(stdout, " - Hardware OPL3 chip in use\n"); #else diff --git a/utils/vlc_codec/libadlmidi.c b/utils/vlc_codec/libadlmidi.c index 5f85a4d..aedd718 100644 --- a/utils/vlc_codec/libadlmidi.c +++ b/utils/vlc_codec/libadlmidi.c @@ -18,14 +18,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. *****************************************************************************/ -//#ifdef HAVE_CONFIG_H -//# include "config.h" -//#endif - #include <vlc_common.h> #include <vlc_plugin.h> #include <vlc_codec.h> #include <vlc_dialog.h> +#include <libvlc_version.h> #include <unistd.h> @@ -43,18 +40,20 @@ #define SOUNDFONT_LONGTEXT N_( \ "Custom bank file to use for software synthesis." ) -//#define CHORUS_TEXT N_("Chorus") +#if 0 /* Old code */ +#define CHORUS_TEXT N_("Chorus") -//#define GAIN_TEXT N_("Synthesis gain") -//#define GAIN_LONGTEXT N_("This gain is applied to synthesis output. " \ -// "High values may cause saturation when many notes are played at a time." ) +#define GAIN_TEXT N_("Synthesis gain") +#define GAIN_LONGTEXT N_("This gain is applied to synthesis output. " \ + "High values may cause saturation when many notes are played at a time." ) -//#define POLYPHONY_TEXT N_("Polyphony") -//#define POLYPHONY_LONGTEXT N_( \ -// "The polyphony defines how many voices can be played at a time. " \ -// "Larger values require more processing power.") +#define POLYPHONY_TEXT N_("Polyphony") +#define POLYPHONY_LONGTEXT N_( \ + "The polyphony defines how many voices can be played at a time. " \ + "Larger values require more processing power.") -//#define REVERB_TEXT N_("Reverb") +#define REVERB_TEXT N_("Reverb") +#endif #define SAMPLE_RATE_TEXT N_("Sample rate") @@ -67,7 +66,11 @@ static void Close (vlc_object_t *); vlc_module_begin () set_description (N_("ADLMIDI OPL3 Synth MIDI synthesizer")) +#if (LIBVLC_VERSION_MAJOR >= 3) + set_capability ("audio decoder", 150) +#else set_capability ("decoder", 150) +#endif set_shortname (N_("ADLMIDI")) set_category (CAT_INPUT) set_subcategory (SUBCAT_INPUT_ACODEC) @@ -105,7 +108,11 @@ static const struct ADLMIDI_AudioFormat g_output_format = }; //static int DecodeBlock (decoder_t *p_dec, block_t *p_block); //For different version +#if (LIBVLC_VERSION_MAJOR >= 3) +static int DecodeBlock (decoder_t *p_dec, block_t *p_block); +#else static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block); +#endif static void Flush (decoder_t *); static int Open (vlc_object_t *p_this) @@ -149,10 +156,12 @@ static int Open (vlc_object_t *p_this) date_Set (&p_sys->end_date, 0); p_dec->p_sys = p_sys; - //==For different version== - //p_dec->pf_decode = DecodeBlock; - //p_dec->pf_flush = Flush; +#if (LIBVLC_VERSION_MAJOR >= 3) + p_dec->pf_decode = DecodeBlock; + p_dec->pf_flush = Flush; +#else p_dec->pf_decode_audio = DecodeBlock; +#endif return VLC_SUCCESS;//VLCDEC_SUCCESS } @@ -168,134 +177,61 @@ static void Close (vlc_object_t *p_this) static void Flush (decoder_t *p_dec) { decoder_sys_t *p_sys = p_dec->p_sys; - +#if (LIBVLC_VERSION_MAJOR >= 3) date_Set (&p_sys->end_date, VLC_TS_INVALID); +#else + date_Set (&p_sys->end_date, 0); +#endif adl_panic(p_sys->synth); } +#if (LIBVLC_VERSION_MAJOR >= 3) +static int DecodeBlock (decoder_t *p_dec, block_t *p_block) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + block_t *p_out = NULL; +#else static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block) { block_t *p_block; decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_out = NULL; - if (pp_block == NULL) return NULL; p_block = *pp_block; - if (p_block == NULL) - return NULL; - *pp_block = NULL; - - if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) - { - date_Set (&p_sys->end_date, 0); - adl_panic(p_sys->synth); - } - - if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date)) - date_Set (&p_sys->end_date, p_block->i_pts); - else - if (p_block->i_pts < date_Get (&p_sys->end_date)) - { - msg_Warn (p_dec, "MIDI message in the past?"); - goto drop; - } - - if (p_block->i_buffer < 1) - goto drop; - - uint8_t event = p_block->p_buffer[0]; - uint8_t channel = p_block->p_buffer[0] & 0xf; - event &= 0xF0; - - if (event == 0xF0) - switch (channel) - { - case 0: - if (p_block->p_buffer[p_block->i_buffer - 1] != 0xF7) - { - case 7: - msg_Warn (p_dec, "fragmented SysEx not implemented"); - goto drop; - } - //fluid_synth_sysex (p_sys->synth, (char *)p_block->p_buffer + 1, - // p_block->i_buffer - 2, NULL, NULL, NULL, 0); - break; - case 0xF: - adl_rt_resetState(p_sys->synth); - break; - } - - uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0; - uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0; +#endif - switch (event & 0xF0) + if (p_block == NULL) { - case 0x80: - adl_rt_noteOff(p_sys->synth, channel, p1); - break; - case 0x90: - adl_rt_noteOn(p_sys->synth, channel, p1, p2); - break; - /*case 0xA0: note aftertouch not implemented */ - case 0xB0: - adl_rt_controllerChange(p_sys->synth, channel, p1, p2); - break; - case 0xC0: - adl_rt_patchChange(p_sys->synth, channel, p1); - break; - case 0xD0: - adl_rt_channelAfterTouch(p_sys->synth, channel, p1); - break; - case 0xE0: - adl_rt_pitchBendML(p_sys->synth, channel, p2, p1); - break; +#if (LIBVLC_VERSION_MAJOR >= 3) + return VLCDEC_SUCCESS; +#else + return p_out; +#endif } - unsigned samples = - (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000; - if (samples == 0) - goto drop; - - p_out = decoder_NewAudioBuffer (p_dec, samples); - if (p_out == NULL) - goto drop; - - p_out->i_pts = date_Get (&p_sys->end_date ); - samples = adl_generateFormat(p_sys->synth, (int)samples * 2, - (ADL_UInt8*)p_out->p_buffer, - (ADL_UInt8*)(p_out->p_buffer + g_output_format.containerSize), - &g_output_format); - samples /= 2; - p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts; - -drop: - block_Release (p_block); - return p_out; -} - -#if 0 -static int DecodeBlock (decoder_t *p_dec, block_t *p_block) -{ - decoder_sys_t *p_sys = p_dec->p_sys; - block_t *p_out = NULL; - - if (p_block == NULL) /* No Drain */ - return VLC_SUCCESS;//VLCDEC_SUCCESS +#if (LIBVLC_VERSION_MAJOR < 3) + *pp_block = NULL; +#endif if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) { +#if (LIBVLC_VERSION_MAJOR >= 3) Flush (p_dec); if (p_block->i_flags & BLOCK_FLAG_CORRUPTED) { block_Release(p_block); - return VLC_SUCCESS;//VLCDEC_SUCCESS + return VLCDEC_SUCCESS; } +#else + Flush (p_dec); +#endif } - if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date)) + if (p_block->i_pts > VLC_TS_INVALID + && !date_Get (&p_sys->end_date)) date_Set (&p_sys->end_date, p_block->i_pts); else if (p_block->i_pts < date_Get (&p_sys->end_date)) @@ -360,21 +296,30 @@ static int DecodeBlock (decoder_t *p_dec, block_t *p_block) if (samples == 0) goto drop; +#if (LIBVLC_VERSION_MAJOR >= 3) if (decoder_UpdateAudioFormat (p_dec)) goto drop; +#endif + p_out = decoder_NewAudioBuffer (p_dec, samples); if (p_out == NULL) goto drop; p_out->i_pts = date_Get (&p_sys->end_date ); - p_out->i_length = date_Increment (&p_sys->end_date, samples) - - p_out->i_pts; - adl_generate(p_sys->synth, samples * 2, p_out->p_buffer); + samples = adl_generateFormat(p_sys->synth, (int)samples * 2, + (ADL_UInt8*)p_out->p_buffer, + (ADL_UInt8*)(p_out->p_buffer + g_output_format.containerSize), + &g_output_format); + samples /= 2; + p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts; + drop: block_Release (p_block); +#if (LIBVLC_VERSION_MAJOR >= 3) if (p_out != NULL) decoder_QueueAudio (p_dec, p_out); - return VLC_SUCCESS;//VLCDEC_SUCCESS -} - + return VLCDEC_SUCCESS; +#else + return p_out; #endif +} |